I'm writing a basic hello world program in x86_64 GNU Assembly on Windows. Since I could not find a working example for Windows, I've been following a tutorial for Linux, replacing the syscalls with Windows kernel32 calls.
The person in the tutorial is using leaq
to load the address of a string to be printed, when I try this, I get a linking error relocation truncated to fit: R_X86_64_32S against '.rodata'
. If I try to load the string with movabsq
instead, which I found by googling that error above, the program links and runs correctly.
This is the assembly with leaq
(not working):
.extern GetStdHandle
.extern WriteFile
.extern ExitProcess
.global _start
.section .rodata
msg: .ascii "Hello World!\n"
.section .text
_start:
# stdout = GetStdHandle(-11)
movq $-11, %rcx
call GetStdHandle
# WriteFile(stdout, msg, 13, 0, 0)
movq %rax, %rcx
leaq msg, %rdx
movq $13, %r8
movq $0, %r9
push $0
call WriteFile
# ExitProcess(0)
xor %rcx, %rcx
call ExitProcess
This is the assembly with movabsq
(working):
.extern GetStdHandle
.extern WriteFile
.extern ExitProcess
.global _start
.section .rodata
msg: .ascii "Hello World!\n"
.section .text
_start:
# stdout = GetStdHandle(-11)
movq $-11, %rcx
call GetStdHandle
# WriteFile(stdout, msg, 13, 0, 0)
movq %rax, %rcx
movabsq $msg, %rdx
movq $13, %r8
movq $0, %r9
push $0
call WriteFile
# ExitProcess(0)
xor %rcx, %rcx
call ExitProcess
Why is my program not linking with leaq
like it did in the tutorial? What is the difference between leaq
and movabsq
?
Thanks in advance!