0

I'm trying to understand how $ works in nasm. I read this answer and wrote the following example:

section .text
    global _start

_start:
    mov rax, 0x01 
    mov rdi, 0x01
    mov rsi, str
    mov rdx, str_len
    syscall

    mov rax, 60
    syscall

segment .data
    str: db 'Some string',0x0a,0x0d
    str_len: equ $ - str

The program works as expected. It prints

Some string

but if I replace equ with db

segment .data
    str: db 'Some string',0x0a,0x0d
    str_len: db $ - str ; equ --> db

it starts printing lots of garbage data:

Some string
�@`
```"`)`main.asmstrstr_len__bss_start_edata_end.symtab.strtab.shstrtab.text.data�'!`'    .
St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • Do you understand the difference between `equ` and `db`? – Oliver Charlesworth Dec 23 '17 at 19:42
  • @OliverCharlesworth I though I understood. EQU behaves simila to macro declaration in C. – St.Antario Dec 23 '17 at 19:52
  • switching on listing file and checking it out will often help to get better idea, what is the actual product of the assembler. – Ped7g Dec 23 '17 at 20:29
  • 3
    Basically in your second case the `mov rdx, str_len` is loading `rdx` with memory address, instead of length, because you turned the length "macro" symbol (defined by `equ` to have value `13`) into label ahead of `db` (much more than `13` = lot of output = garbage). And don't use colon with `equ`, they don't belong there. Makes me wishing the NASM would report it as error, not sure why it *does* compile, as it makes no sense, colon should mark memory label, like in your second case. To use your second case def you would need `movzx edx,byte [str_len]` (`rdx` = the byte `13` defined in memory) – Ped7g Dec 23 '17 at 20:34
  • 2
    In both cases the `$` is still same, as it marks the memory address of *current* position (start of line), so it doesn't matter whether you didn't emit any new machine code byte, just defined compile time constant (`equ`), or you did emit machine code byte (`db`), because that happens as result of line where you use `$`, so the expression itself "`$ - str`" will evaluate to `13` in both cases. It's just used differently, either assigned as value of `str_len` symbol, or used as memory content for `db` directive (not assigned to `str_len` symbol, which is memory label pointing to defined byte). – Ped7g Dec 23 '17 at 20:42
  • @Ped7g Thanks for your comment. Understood :) – St.Antario Dec 23 '17 at 21:09

0 Answers0