2

I have the following assembly code

        global   main 
        extern   println
    
        section  .text
    
main:
        mov rdi, message
        call     println
        ret

message:
        db "Hello, world!", 0

I am linking it with some C code

#include <stdio.h>

void println(char *line) {
    puts(line);
}

I run the following commands to compile and link these two programs

nasm -f elf64 helloWorld.asm -o helloWorld.asm.o
gcc -c helloWorld.c -o helloWorld.c.o
gcc -static helloWorld.c.o helloWorld.asm.o -o helloWorld

then I run my finished program with

./helloWorld

If I remove -static from the gcc options, I get a seg-fault! Why is this??

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
doliphin
  • 752
  • 6
  • 22
  • If you 16-byte align the stack in `main` by making the first instruction `push rbp` and do a `pop rbp` right before the `ret`, what happens? As well you should zero out `al` before calling a variadic function like printf when there are no XMM registers being used to pass things like floats/doubles etc. `xor eax, eax` will zero out RAX(and AL). – Michael Petch Feb 09 '23 at 21:17
  • @MichaelPetch: `println` is not variadic, and itself only uses `puts` not `printf` so there's no need to set AL. It seems the dynamic-library build of glibc ended up with different code-gen than the static `libc.a`, with puts (and the internal stdio functions it calls) only depending on RSP%16==0 before a `call` in `libc.so.6` – Peter Cordes Feb 09 '23 at 21:27
  • @PeterCordes : Sorry I thought it was `printf` lol. So ignore the AL comment. You may have noticed I said `printf` in my comment which would be a hint at my gaff. – Michael Petch Feb 09 '23 at 21:28
  • @MichaelPetch: Yeah, and I had a different brain fart at first: I thought it was going to be [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427) 32-bit absolute addressing, but no, that would be a link error not a segfault. NASM assembles `mov rdi, message` to `mov r64, imm64`, and GCC's CRT code for PIE executables does do runtime fixups (text relocations) on 64-bit absolute addresses. Code like this does get a correct address into a register as long as you aren't writing your own `_start` and linking with `-static-pie` – Peter Cordes Feb 09 '23 at 21:29

0 Answers0