YASM, why the global-extern-linking does not work - undefined

i´m new to assembly and using yasm, with the ebe editor.
Now after the first steps i want to check the global/extern mechanism.
Therefore i made 2 modules:
actor.asm
extern greeter
section .text
global main
main:
push rbp
call greeter wrt ..plt
pop rbp
mov rax,0
ret
greeter.asm
extern printf
section .data
msg: db "Hello world", 0
fmt: db "%s", 10, 0
section .text
global greeter
type greeter function
size greeter greeter.end -greeter
greeter:
push rbp
mov rdi,fmt
mov rsi,msg
mov rax,0
call printf
pop rbp
mov rax,0
ret
.end:
Both files are compiled and when i run the first, following error message appears:
/home/1/Öffentlich/EBE_Space/ext_glob_test/actor.o: In function
main': /home/1/Öffentlich/EBE_Space/ext_glob_test/actor.asm:6:
undefined reference togreeter'
What´s wrong?
What´s necessary to make a global function linkable?
TIA

Related

xcode 13 Assertion failed in function roalloc, file DyldProcessConfig.cpp

Trying to compile and run an app in xcode13, but dyld assertion failed:
dyld[13967]: Assertion failed: (next < &roBuffer[0x8000]), function roalloc, file
DyldProcessConfig.cpp, line 653.
dyld`__abort_with_payload:
0x100cd74d4 <+0>: mov x16, #0x209
0x100cd74d8 <+4>: svc #0x80
-> 0x100cd74dc <+8>: b.lo 0x100cd74fc ; <+40>
0x100cd74e0 <+12>: pacibsp
0x100cd74e4 <+16>: stp x29, x30, [sp, #-0x10]!
0x100cd74e8 <+20>: mov x29, sp
0x100cd74ec <+24>: bl 0x100c8ed68 ; cerror_nocancel
0x100cd74f0 <+28>: mov sp, x29
0x100cd74f4 <+32>: ldp x29, x30, [sp], #0x10
0x100cd74f8 <+36>: retab
0x100cd74fc <+40>: ret
Thread 1: signal SIGABRT
The environment is:
macOS12.0.1, xcode13.1
Anyone know something about this roalloc function and DyldProcessConfig.cpp? I google it but find nothing.

MASM how to make desired function call

I'd like to know, how to do the following.
I have an array, where i have to summ numbers (easy)
but the twist is, that i have to have a function call for it,
that get's is params through specific registers. How do i implement that?
In this case, the function needs to get the array (offset) through ESI, and the length of it through ECX.
please educate me
EDIT:
in the meantime i've conjured up this. No idea if this works to as my MASM compliling just broken itself for no reason
.data
intarray DWORD 10000h,20000h,30000h,40000h
.code
szummer proc uses esi ecx,
ptrArray:PTR DWORD, ;points to the array
szArray: Dword ;array size
mov esi, ptrArray ;address of the array
mov ecx, szArray ;szize
mov eax, 0 ;set to 0
AS1:
add eax, [esi] ;add each int to sum
add esi, 4 ;point to next int
loop AS1 ;reapet for array size
ret;
szummer endp
main proc
mov ecx, OFFSET intarray
mov esi, LENGHTOF intarray
INVOKE ArraySum,ecx,esi
invoke ExitProcess,0
main endp
end main
The MASM directive INVOKE works only with the calling conventions C (cdecl), STDCALL, BASIC, FORTRAN and PASCAL. All of these conventions pass the arguments on the stack. Thus, you can't use INVOKE for passing the arguments in registers. You can use the Assembly instruction CALL instead. Your program - slightly modified ;-) - with MASM32 library included (because of "ExitProcess"):
INCLUDE \masm32\include\masm32rt.inc
.DATA
intarray DWORD 10000h,20000h,30000h,40000h
.CODE
szummer proc uses esi ecx
mov eax, 0 ;set to 0
AS1:
add eax, [esi] ;add each int to sum
add esi, 4 ;point to next int
loop AS1 ;reapet for array size
ret;
szummer endp
main proc
mov esi, OFFSET intarray
mov ecx, LENGTHOF intarray
call szummer
invoke ExitProcess,0
main ENDP
END main

Variable initialization in as8088

I'm currently writing a function that should basically just write characters from a string into variables.
When performing test prints my variables seem fine. But when I attempt to print the first variable assigned(inchar) outside of the function it returns a empty string, but the second variable (outchar) seems to return fine. Am I somehow overwriting the first variable?
This is my code:
_EXIT = 1
_READ = 3
_WRITE = 4
_STDOUT = 1
_STDIN = 1
_GETCHAR = 117
MAXBUFF = 100
.SECT .TEXT
start:
0: PUSH endpro2-prompt2
PUSH prompt2
PUSH _STDOUT
PUSH _WRITE
SYS
ADD SP,8
PUSH 4
PUSH buff
CALL getline
ADD SP,4
!!!!!!!!!
PUSH buff
CALL gettrans
ADD SP,4
ADD AX,1 !gives AX an intial value to start loop
1: CMP AX,0
JE 2f
PUSH endpro-prompt1
PUSH prompt1
PUSH _STDOUT
PUSH _WRITE
SYS
ADD SP,8
PUSH MAXBUFF
PUSH buff
CALL getline
ADD SP,2
!PUSH buff
!CALL translate
!ADD SP,4
JMP 1b
2: PUSH 0 ! exit with normal exit status
PUSH _EXIT
SYS
getline:
PUSH BX
PUSH CX
PUSH BP
MOV BP,SP
MOV BX,8(BP)
MOV CX,8(BP)
ADD CX,10(BP)
SUB CX,1
1: CMP CX,BX
JE 2f
PUSH _GETCHAR
SYS
ADD SP,2
CMPB AL,-1
JE 2f
MOVB (BX),AL
INC BX
CMPB AL,'\n'
JNE 1b
2: MOVB (BX),0
MOV AX, BX
SUB AX,8(BP)
POP BP
POP CX
POP BX
RET
gettrans:
PUSH BX
PUSH BP
MOV BP,SP
MOV BX,6(BP) !Store argument in BX
MOVB (inchar),BL ! move first char to inchar
1: INC BX
CMPB (BX),' '
JE 1b
MOVB (outchar),BL !Move char seperated by Space to outchar
MOV AX,1 !On success
POP BP
POP BX
RET
.SECT .BSS
buff:
.SPACE MAXBUFF
.SECT .DATA
prompt1:
.ASCII "Enter a line of text: "
endpro:
prompt2:
.ASCII "Enter 2 characters for translation: "
endpro2:
outchar:
.BYTE 0
inchar:
.BYTE 0
charct:
.BYTE 0
wordct:
.BYTE 0
linect:
.BYTE 0
inword:
.BYTE 0
This is the code used to test print
PUSH 1 ! print that byte
PUSH inchar
PUSH _STDOUT
PUSH _WRITE
SYS
ADD SP,8
CALL printnl !function that prints new line
PUSH 1 ! print that byte
PUSH outchar
PUSH _STDOUT
PUSH _WRITE
SYS
CALL printnl
ADD SP,8
There seem to be a number of as88 8088 simulator environments. But I noticed on many of the repositories of code this bug mentioned:
1. The assembler requires sections to be defined in the following order:
TEXT
DATA
BSS
After the first occurrences, remaining section directives may appear in any order.
I'd recommend in your code to move the BSS section after DATA in the event your as88 environment has a similar problem.
In your original code you had lines like this:
MOV (outchar),BX
[snip]
MOV (inchar),BX
You defined outchar and inchar as bytes. The 2 lines above move 2 bytes (16-bits) from the BX register to both one byte variables. This will cause the CPU to write the extra byte into the next variable in memory. You'd want to explicitly move a single byte. Something like this might have been more appropriate:
MOVB (outchar),BL
[snip]
MOVB (inchar),BL
As you will see this code still has a bug as I mention later in this answer. To clarify - the MOVB instruction will move a single byte from BL and place it into the variable.
When you do a SYS call for Write you need to pass the address of the buffer to print, not the data in the buffer. You had 2 lines like this:
PUSH (inchar)
[snip]
PUSH (outchar)
The parentheses say to take the value in the variables and push them on the stack. SYS WRITE requires the address of the characters to display. The code to push their addresses should look like:
PUSH inchar
[snip]
PUSH outchar
gettrans function has a serious flaw in handling the copy of a byte from one buffer to another. You have code that does this:
MOV BX,6(BP) !Store argument in BX
MOVB (inchar),BL ! move first char to inchar
1: INC BX
CMPB (BX),' '
JE 1b
MOVB (outchar),BL !Move char seperated by Space to outchar
MOV BX,6(BP) properly places that buffer address passed as an argument and puts it into BX. There appears to be a problem with the lines that look like:
MOVB (inchar),BL ! move first char to inchar
This isn't doing what the comment suggests it should. The line above moves the lower byte (BL) of the buffer address in BX to the variable inchar . You want to move the byte at the memory location pointed to by BX and put it into inchar. Unfortunately on the x86 you can't move the data from one memory operand to another directly. To get around this you will have to move the data from the buffer pointed to by BX into a temporary register (I'll choose CL) and then move that to the variable. The code could look like this:
MOVB CL, (BX)
MOVB (inchar),CL ! move first char to inchar
You then have to do the same for outchar so the fix in both places could look similar to this:
MOV BX,8(BP) !Store argument in BX
MOVB CL, (BX)
MOVB (inchar),CL ! move first char to inchar
1: INC BX
CMPB (BX),' '
JE 1b
MOVB CL, (BX)
MOVB (outchar),CL ! move second char to outchar
The instruction MOV (inchar),BX stores register BX to the memory location labelled inchar.
However, inchar has been defined as a .BYTE, but BX is a 16-bit register, (2 bytes,) so you are writing not only inchar but also outchar.
The only reason why it appears to work in the beginning is because the 8088 is a low-endian architecture, so the low-order byte of BX is being stored first, while the high-order byte follows.
So, try MOV (inchar),BL

Calling a function in Assembler (AT&T, IA-32)

I just started learning Assembler, and I'm stuck at the very beginning - I'm trying to call a simple function - in fact it's mostly copied from a book, and I keep getting segmentation fault. Maybe someone more experienced could point out what's wrong with this code:
.code32
SYSEXIT = 1
.data
.text
.globl _start
_start:
push $28 #just some random argument
push $33
call myfunc
mov $SYSEXIT, %eax
#exit code is stored in ebx after calling function
int $0x80
.type myfunc, #function
myfunc:
push %ebp #save old base pointer on a stack
movl %esp, %ebp
movl 8(%ebp), %ebx #first argument to ebx
movl 12(%ebp), %ecx #second argument to ecx
addl %ecx, %ebx #add arguments together - store them in ebx
movl %ebp, %esp
pop %ebp
ret
Your function expects the arguments to be longs (32-bit), so you should push them with pushl rather than push.
You should also make sure that you balance the stack after the function returns. I.e. something like:
pushl $28
pushl $33
call myfunc
addl $8,%esp # "removes" two 32-bit arguments off the stack

x86 simple function not working

Hi guys I am trying to build the following function
function int Main(){
return 5;
}
this is my assembly code:
.globl Main
Main:
pushl %ebp
movl %esp, %ebp
subl $0, %esp
pushl $5
movl %ebp, %esp
popl %ebp
ret
However this always returns 1 it never returns 5 why?
How about just:
Main:
push byte 5
pop eax
ret
Summarizing what everyone said: your primary error is that the return value should go into EAX and it does not. Prolog and epilog code are not necessary for simple functions like this, but they won't hurt either (as long as they don't unbalance the stack). So the assembly should go:
(prolog)
movl $5, %eax,
(epilog)
ret
Where prolog and epilog are whatever your compiler generates by default.