Why there is always a useless function argument in stack?

assembly, freebsd

Solution

It's a dummy argument to increase performance slightly by preventing a call/ret instruction pair.

See $2.1 in the below link:

http://www.int80h.org/bsdasm/#default-calling-convention

Problem

I'm learning assembly language programming on FreeBSD. I'm using FreeBSD 9.0 i386 release and nasm assembler. When I wrote a simple syscall function, I found that I had to push a useless value into the stack to make the code run correctly. For example: ``` ; File:test.asm section .text global _start _start: xor eax,eax ; Argument of exit() push 0x0 ; Syscall of exit() mov al,1 int 0x80 ``` I used the following command to assemble and link the above code: ``` %nasm -f elf test.asm -o test.o %ld test.o -o test.bin ``` I used ktrace to inspect the program and found: ``` %ktrace ./test.bin %kdump -d -f ./ktrace.out 2059 ktrace RET ktrace 0 2059 ktrace CALL execve(-1077940941,-1077941260,-1077941252) 2059 ktrace NAMI "./test.bin" 2059 test.bin RET execve 0 2059 test.bin CALL exit(1) ``` So the code didn't run correctly, cause I provided 0 as the only argument of exit() but the program actually run exit(1). Then I changed my code. ``` ; File:test.asm section .text global _start _start: xor eax,eax push 0x0 ; Whatever digits,0x1,0x2...0xFFFFFFFF, ect. push 0xFFFFFFFF mov al,1 int 0x80 ``` Then the code was executed correctly. At first, I though it was because of something like "stack padding" or "stack alignment", like Stack allocation, padding, and alignment. So it might respect 16-bit alignment. But I found it not. For example, This following code: ``` ; File:test.asm section .text global _start _start: xor eax,eax push 0x0 ; Actual argument of exit() push 0x3 push 0xFFFFFFFF ; Syscall of exit() mov al,1 int 0x80 ``` actually executed exit(3). It seemed that it didn't align bytes. I debug the above code with gdb, when the last line was about to be executed, the stack was something like this: ``` 0xFFFFFFFF -> esp 0x00000003 0x00000000 ``` So here's my question: why there's always a useless argument or is there a method to work around?

Original source

Related problems