0

I try to understand why in this asm code using LEA or MOV instruction to obtain a label address ( compiled with nasm ) :

BITS 16

org 100h

section .text
    global _start

_start:
    mov ah, 0
    jmp short rel8off
    mov ah, 1
    mov bh, 0
    jmp rel16off
    mov bh, 1
    mov ch, 0
    jmp reg
    mov ch, 1
    jmp end

rel8off:
    jmp $+2

rel16off:
    jmp short $+2

reg:
    lea dx, [end]
    jmp dx

end:
    mov ax, 0
    int 0x20

section .data
  

section .bss

The value stocked in the register 'DX' in the 'reg' label is 0x11e ? For understand my question you can find here the decompilation of previous code :

00000000  B400              mov ah,0x0
00000002  EB10              jmp short 0x14
00000004  B401              mov ah,0x1
00000006  B700              mov bh,0x0
00000008  EB0C              jmp short 0x16
0000000A  B701              mov bh,0x1
0000000C  B500              mov ch,0x0
0000000E  EB08              jmp short 0x18
00000010  B501              mov ch,0x1
00000012  EB0A              jmp short 0x1e
00000014  EB00              jmp short 0x16
00000016  EB00              jmp short 0x18
00000018  8D161E01          lea dx,[0x11e]
0000001C  FFE2              jmp dx
0000001E  B80000            mov ax,0x0
00000021  CD20              int 0x20

The 'end' label is in 0000001E memory location. Why the compiler generate for lea dx, [end] instruction : 8d161e01 and not 8d161e00 ?

  • 8d is the opcode for LEA instruction.
  • 16 is the destination operand ( DX register in this example )
  • 1e01, 1e is the position of 'end' label but 01 ??????

Its the same result if I use 'mov' instruction like : mov dx, [end]

Thanks for yours explanations/help.

Jester
  • 56,577
  • 4
  • 81
  • 125
ExecAssa
  • 177
  • 11
  • 4
    You forgot the `org 100h`. Your `end` is therefore not at `1E` but at `011E` which in little endian is `1E 01`. – Jester Feb 05 '23 at 12:56
  • 1
    Ok ! Well I understand better now, thanks for your help Jester! – ExecAssa Feb 05 '23 at 13:00
  • 2
    Those are file offsets, not memory addresses (actually offsets in seg:off logical addressing). Similar to [Why does first address equal 0000 when .org 8000 in assembly?](https://stackoverflow.com/a/74962302) but not quite a duplicate since this is `ndisasm` disassembly. There is no metadata to signal the load address, and ndisasm doesn't do metadata anyway. Surprisingly even a NASM listing (`nasm -l /dev/stdout -f bin foo.asm`) uses file offsets, not addresses, even though it can see the source with the `org 100h`. – Peter Cordes Feb 05 '23 at 20:33
  • Thanks for this interesting and educational answer Peter Cordes. – ExecAssa Feb 05 '23 at 21:20
  • 2
    @PeterCordes It makes sense for NASM to display offsets. They are not file offsets they are "section offsets". They can be handy to inspect opcodes and the binary layout of the code and the data. I didn't know NASM could produce such listings. Cool! – Margaret Bloom Feb 05 '23 at 23:21
  • 1
    @MargaretBloom: Oh yes, you're right, the NASM `-l` listing resets the the offset to zero for `.data` if you put anything in there, so those are section offsets, like if you use `mov ax, $` you get `0x23` at the end of .text, not `0x123`. (`ndisasm` of course won't reset its position counter; it doesn't know about sections, and there's no metadata to indicate them anyway, so for ndisasm it actually is file offsets.) – Peter Cordes Feb 05 '23 at 23:27

0 Answers0