1

I'm trying to save callee-saved registers. In the following code I only try to save %r15 (the behavior is the same when other callee-saved registers are saved, one or all).

 .data
     hello: .string "Hello"
     format: .asciz "%s\n"
 .text
     .global _main
 _main:
   pushq %rbp
   pushq %r15
   leaq format(%rip), %rdi
   leaq hello(%rip), %rsi
   callq _printf
   popq  %r15
   popq  %rbp
   movq  $0, %rax
   retq

The result is Segmentation fault: 11. When pushq %r15 and popq %r15 are commented, the program outputs Hello as expected.

What's the reason for the Segmentation fault? The problem is reproducible on my Ubuntu and OS X systems, but not on Ubuntu subsystem in Windows.

The code is compiled as gcc test.s. On OS X:

$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
  • 5
    You misaligned the stack. It needs to be 16 byte aligned as per calling convention. Also you should zero `%al` before calling `printf` (means the number of SSE registers used for a varargs function). Consult the ABI docs for details. – Jester Sep 27 '18 at 21:54
  • @Jester, Thank you very much! –  Sep 27 '18 at 22:01
  • AL is probably non-zero, so the library implementation of `printf` is probably doing 8 `movaps` instructions to store the XMM0..7 registers to the stack. Or maybe current OS X `printf` simply assumes stack alignment for something else, and would fault on a misaligned stack even with `al=0`. – Peter Cordes Sep 28 '18 at 01:53

0 Answers0