0

I wrote the following assembly

$ cat l0_basic.asm 
BITS 64

_start:
  mov rax, 59             ; this is the syscall number of execve
  lea rdi, [rel binsh]  ; points the first argument of execve at the /bin/sh string below
  mov rsi, 0              ; this makes the second argument, argv, NULL
  mov rdx, 0              ; this makes the third argument, envp, NULL
  syscall                 ; this triggers the system call

section .data
  binsh: db `/bin/sh` ; a label marking where the /bin/sh string is

Then assemble it with

$ nasm -felf64 l0_basic.asm -o l0_basic.o
$ objdump -d l0_basic.o 

l0_basic.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <_start>:
   0:   b8 3b 00 00 00          mov    eax,0x3b
   5:   48 8d 3d 00 00 00 00    lea    rdi,[rip+0x0]        # c <_start+0xc>
   c:   be 00 00 00 00          mov    esi,0x0
  11:   ba 00 00 00 00          mov    edx,0x0
  16:   0f 05                   syscall 

You can see it changes rax to eax, rsi to esi. I dont want this automatic conversion. How can I make nasm keep the same instruction I wrote?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
drdot
  • 3,215
  • 9
  • 46
  • 81
  • @ThomasJager Helps! I was able to force it by using gcc with .s file, but good to know the .asm way too. – drdot Feb 06 '21 at 17:20
  • 1
    The `lea` is the only instruction that needs to be 64-bit. Writing a 32-bit register automatically zero-extends to 64 bits. So the changes done by NASM seem to be semantically equivalent optimisations. – ecm Feb 06 '21 at 20:34
  • This is an optimisation nasm performs. The 32 bit instruction performs the same operation as the 64 bit instruction but is one byte shorter. – fuz Feb 06 '21 at 21:30
  • 1
    You can use `nasm -O0` to disable optimization if you don't want it to pick the shortest encoding that's architecturally equivalent. Or even `-O1` still skips that optimization, giving a horrible `48 b8 00 00 00 00 00 00 00 00 movabs rax,0x0` (`mov rax, strict qword 0`) instead of the `mov rax, sign_extended_imm32` I expected. Clearly NASM isn't intended to be used without optimization enabled because even with source-level optimization you couldn't get efficient asm. (except with `mov rax, strict dword -1`) – Peter Cordes Feb 06 '21 at 23:10

0 Answers0