1

I have the following Assembly code:

section .text
      global _start
_start:
       mov edx,len2
       mov ecx,msg1
       mov ebx,1
       mov eax,4
       int 0x80     ; write(1, msg1, len2)
       mov eax,1  ;system call number (sys_exit) 
       int 0x80   ;call kernel

section  .data

   msg1 db   'Hello '
   len1 equ  $ - msg1
   msg2 db   'world!',0xa
   len2 equ  $ - msg1

I have been told that this code should print "Hello World!" but I can't understand why?

When I first looked at it I was sure it supposed to print just "Hello ". Can someone please help me to understand this, please?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Eli Zatlawy
  • 678
  • 10
  • 24

1 Answers1

4

as @Jester said in the comment the reason is that len2 is defined as $ - msg1 not as $ - msg2 so it includes the length of the Hello as well.

Eli Zatlawy
  • 678
  • 10
  • 24
  • 1
    Related: [How does $ work in NASM, exactly?](https://stackoverflow.com/q/47494744). The code in your question looks like an intentional trick / obfuscation: defining len2 as the total length, but calling it len2 is super weird. So the actual length of the 2nd part is `len2 - len1`, which you'd need if you ever wanted to print just the "world!" part. – Peter Cordes Jan 15 '21 at 10:20
  • @PeterCordes yes, this is a question from a previous exam about Assembly that I'm learning to. – Eli Zatlawy Jan 15 '21 at 11:28
  • Ok, but if I ever saw code like that in real life, I'd fix it by renaming `len2` to `len_total`. As written, it's intentionally misleading naming, to the point where I'd consider it a bug. IDK if that makes a good exam question or not. Using `len2` with `msg1` in the code does encourage you to look closely at how they're defined, instead of assuming that they're defined the way you'd expect (as the length of the corresponding message number). – Peter Cordes Jan 15 '21 at 11:33