I have the following code all it is suppose to do is print Hello World using CoreFoundation functions. However whenever I seemingly have a proper aligned stack it doesn't work, seg faulting. But then when I finally got it working the stack isn't aligned?!?!?!
global _main
align 4, db 0x90
extern _CFStringCreateWithCString
extern _CFShow
section .data
hw: db 'Hello World!' ,0xA,0
section .text
_main: ; entering a new function stack must be balanced right?
push ebp ; saving ebp (esp + 4)
mov ebp, esp ; moving registers around
; align stack as calling pushed a 4 byte address on to the stack
sub esp, 12 ; balancing the stack back to mod 16 (4 + 12 = 16)
push 8 ; 4 bytes
push hw ; 4 bytes
push 0 ; 4 bytes
call _CFStringCreateWithCString ; 4 bytes
; stack still balanced
sub esp, 12 ; 12 bytes
push eax ; 4 bytes
call _CFShow ; 4 bytes
; that is 20 bytes?!?!? yet when I change the 12 to an 8 it doesn't run and instead segfaults! When I have the stack balanced!
mov eax, 99 ; return value
mov esp, ebp ; restore stack for function that called us
pop ebp
ret ; return
When run it works, however I can find no reason why it does. I have to subtract 12 from esp for a one argument function. Shouldn't it be 8, doesn't push already handle incrementing the stack for the argument?
I'm not sure why the original function is doing additional subtractions from the stack without using the space which is so allocated on the stack. The stack grows down on the x86. In this context, if you do:
you are allocating (making available)
NUMBER
bytes on the stack to be used for some purpose.I'm making an assumption that the library follows a C calling convention:
With these things in mind, here's how I'd write your function:
Note that since the last
mov
instruction restores the stack, then the lastadd esp,4
could be omitted, but it's here for completeness.MacOS requires / guarantees 16-byte alignment of the stack pointer for function calls. To do this:
Likewise as in the first case, the last
add esp,24
could be omitted.