3

I'm having trouble understanding the difference between the two, the following example really had me puzzled:

section .data
msg: db "Thank you"
var: dd 0x31323334
len equ msg-4

section .text
global main
main:
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, var-len
section .data
%define len msg-4
msg: db "Thank you"
var: dd 0x31323334


section .text
global main
main:
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, var-len

The first program prints "Thank you4321", which is quite obvious, but for some reason the second program prints "Thank" I've tried tracking the values and I got : var = 0x2011, msg = 0x2008, len = 0x2004, but somehow edx got 0x05 where I would think it'd be 0x2011-0x2004 = 0x0D Any idea why this is? Another thing I noticed with equ is that if I calculate len-var I get 0 , my guess is that it has no address in memory because it's a macro? Is this correct? Thanks in advance.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
giorgioh
  • 377
  • 1
  • 13
  • I have fixed your code. You should always copy and paste your code into Stackoverflow. You spelled `define` wrong and you left out `dd` when defining `var`. – Michael Petch Jul 03 '20 at 14:52
  • Thanks and sorry about that. – giorgioh Jul 03 '20 at 16:37
  • 1
    Just for the record, `len equ msg-4` has a totally misleading name. Don't call it `len`, it's the address of 4 bytes before `msg`. See [How does $ work in NASM, exactly?](https://stackoverflow.com/q/47494744) - normally you'd `len equ var - msg`, or (right after msg, before var) `len equ $-msg`. I assume you were playing around starting with something like that and didn't change the name after modifying it to be totally different. – Peter Cordes Jul 03 '20 at 21:24

1 Answers1

5

The first code works because when you use EQU, this line:

len equ msg-4

sets len to the value computed from the expression msg-4 and the result is stored in the constant len. Then when you do:

mov edx, var-len

The precomputed value of len is subtracted from the offset of var which will be 13 which is what you'd expect.

When you use:

%define len msg-4

it defines len to be the string msg-4. When you use len like this:

mov edx, var-len

Text substitution turns it into this:

mov edx, var-msg-4

Which will yield the value 5. This is not the calculation you wanted. What you want it to produce is:

mov edx, var-(msg-4)

To do that change the %define statement to be:

%define len (msg-4)

When text substitution is done it will yield the expression:

mov edx, var-(msg-4)

When computed it should produce the value 13 and put it in EDX.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198