1

I played with assembly on my PC. I wrote following program which ouputs a string first via the write syscall of Linux and second via a call to printf

.text
.global main

main:
# write syscall
movl $4, %eax
movl $1, %ebx
movl $message, %ecx
movl $len, %edx
int $0x80
#push %rax

# printf
push %rbp
mov %rsp,%rbp

mov $message, %rdi
callq printf

pop %rbp
#pop %rax

movl $0x0, %eax
retq
.data

message: .ascii "Hello World, I'm an assembly program\n\0"

len = . - message - 1

The program works fine. But as soon as I uncomment the two push/pop %rax commands the program throws a segmentation fault inside the printf routine. The push/pop has no sense in this case but i wonder why it destroys the printf.

Why does this happen?

Thank you

GNA
  • 479
  • 3
  • 18
  • 9
    Stack pointer needs to be 16 byte aligned, see the ABI documentation. Furthermore, for varargs functions (and `printf` is one) `al` has to contain the number of SSE registers used (zero in this case). PS: don't use 32 bit system calls in 64 bit mode, also `ebx` is callee-saved register. – Jester Jun 30 '16 at 13:31
  • 2
    If you used a debugger, you could see exactly which instruction was segfaulting. See also the [x86 tag wiki](http://stackoverflow.com/tags/x86/info) for more links (e.g. to the ABI docs) – Peter Cordes Jun 30 '16 at 13:35
  • @Jester System V Application Binary Interface draft 1.0: *3.2.3 Parameter Passing [...] For calls that may call functions that use varargs or stdargs (prototype-less calls or calls to functions containing ellipsis (. . . ) in the declaration) %al 16 is used as hidden argument to specify the number of vector registers used. The contents of %al do not need to match exactly the number of registers, but must be an upper bound on the number of vector registers used and is in the range 0–8 inclusive.* – EOF Jun 30 '16 at 21:39
  • @EOF he didn't set it to anything, it's the return value from the syscall, which is the number of bytes written and that's gonna be more than 8. Other than that, not sure what your point is. I told him to read the ABI docs :) Note that had he set it to zero, `printf` probably wouldn't have faulted, it's only used the aligned instructions to save the non-existent floating arguments due to the bad value in `al`. – Jester Jun 30 '16 at 22:07

0 Answers0