Get 32-bit registers from 64-bit nasm code
I am learning 64 bit nasm, I am compiling a .nasm file which ONLY contains 64 bit registers by doing the following
nasm -f elf64 HelloWorld.nasm -o HelloWorld.o
and link it by doing the following
ld HelloWorld.o -o HelloWorld
the program works correctly and even says it is 64-bit ELF when I run the command file
, but when I use objdump
or gdb
to unmount the executable, the registers I put as 64-bit registers in the code show up as 32-bit registers when disassembled ... (example: rax
in the source it is displayed as eax
in disassembly)
Why is this?
This does not happen on just one computer, and this is a new problem, this has not been done before.
HelloWorld.nasm:
global _start
section .text
_start:
mov rax, 1
mov rdi, 1
mov rsi, hello_world
mov rdx, length
syscall
mov rax, 60
mov rdi, 11
syscall
section .data
hello_world: db 'Hello World',0xa
length: equ $-hello_world
Demonstrated by HelloWorld:
...
00000000004000b0 <_start>:
4000b0: b8 01 00 00 00 mov eax,0x1
4000b5: bf 01 00 00 00 mov edi,0x1
4000ba: 48 be d8 00 60 00 00 movabs rsi,0x6000d8
4000c1: 00 00 00
4000c4: ba 0c 00 00 00 mov edx,0xc
4000c9: 0f 05 syscall
4000cb: b8 3c 00 00 00 mov eax,0x3c
4000d0: bf 0b 00 00 00 mov edi,0xb
4000d5: 0f 05 syscall
...
source to share
Why
...
mov rax, 1
mov rdi, 1
mov rsi, hello_world
...
understands how
...
4000b0: b8 01 00 00 00 mov eax,0x1
4000b5: bf 01 00 00 00 mov edi,0x1
4000ba: 48 be d8 00 60 00 00 movabs rsi,0x6000d8
4000c1: 00 00 00
...
Since the letter 0x1
fits into 32 bits, and the upper 32 bits of a 64-bit register are set to 0
when loading the lower 32 bits through the corresponding register E
. Hence the assembler can optimize mov
for 32-bit operation.
Note that the address loaded into rsi
may not fit into 32 bits, hence it rsi
remains so.
If you add the following instructions, you can see the effect very clearly:
mov rbx, 0x0ffffffff ; still fits into 32 bit
mov rbx, 0x100000000 ; does not fit into 32 bits anymore
understands how
a: bb ff ff ff ff mov $0xffffffff,%ebx
f: 48 bb 00 00 00 00 01 movabs $0x100000000,%rbx
16: 00 00 00
You can turn off nasm optimizations with -O0
, in which case the instructions keep their long format:
nasm -O0 -f elf64 HelloWorld.asm
Result:
14: 48 bb ff ff ff ff 00 movabs $0xffffffff,%rbx
1b: 00 00 00
1e: 48 bb 00 00 00 00 01 movabs $0x100000000,%rbx
25: 00 00 00
source to share