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
...

      

+3


source to share


1 answer


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 

      

+4


source







All Articles