You are not logged in.
Pages: 1
I'm trying to learn a little bit about assembly and such, so I made a multi-language program to figure out a little bit. It's very simplistic, but it accomplished what I want for the most part.
Here is what I wrote mix_asm.asm:
section .data
new_line db 0xa
nl_len equ $ - new_line
section .text
global print_str
print_str:
;prologue
push ebp
mov ebp,esp
push eax
push ebx
push ecx
push edx
mov ecx,[ebp+8]
push ecx
call str_length
mov edx,eax
mov ecx,[ebp+8]
mov ebx,1
mov eax,4
int 0x80
call print_nl
;epilogue
pop edx
pop ecx
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
str_length:
;prologue
push ebp
mov ebp,esp
push ebx
push ecx
mov ecx,0
mov ebx,[ebp+8]
while_1:
cmp word [ebx+ecx],0x0
je while_1_end
add ecx,1
jmp while_1
while_1_end:
mov eax,ecx
;epilogue
pop ecx
pop ebx
mov esp,ebp
pop ebp
ret
print_nl:
;prologue
push ebp
mov ebp,esp
push eax
push ebx
push ecx
push edx
mov edx,nl_len
mov ecx,new_line
mov ebx,1
mov eax,4
int 0x80
;epilogue
pop edx
pop ecx
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
and mix_c.c
/* test asm linking in c for *nix */
extern void print_str (char*);
int main ()
{
print_str( "Hello world!" );
return 0;
}
Now then, I can get it to work using elf format through nasm and linking with gcc. If I link with ld (ld -e main -o mix mix_asm.o mix_c.o) though, it returns with a segmentation fault. After executing through the end of the c:main function, it returns to address 0x1 (found using gdb), and I don't understand why. Is it something missing from the linker? A less pressing question, is there a way to get it to successfully link without using the elf format option in nasm? I'd greatly appreciate any help anyone can offer.
Offline
- First point to make: you do not need to save eax, ecx, edx, and esp in print_str. Only ebx, esi, edi, and ebp need to be preserved.
- At while_1, you should be comparing the byte at [ebx+ecx] to 0, not the word.
You need the ELF option to nasm because otherwise it just produces `bin' format output, which won't link into an ELF executable.
And finally the reason it segfaults: ld with -emain treats main() as an entry point, which it actually isn't. With main() as your entry point, when it hits the "return 0;", it will try to jump to whatever address is on the stack behind ebp, which is 0x1 for some reason. GCC will correctly link in the default C runtime (crt{1,i,n}.o among others), which actually call the main() function, whereas ld won't. gcc -v gives a good idea of how gcc is calling the linker.
Offline
Pages: 1