Hello World printing both messages with one system call? Why does length equ $-msg1 include both?

Viewed 41
section.text:
global _start

_start:
    mov ebx, 1
    mov eax, 4
    mov ecx, msg1
    mov edx, len1
    int 0x80

    mov eax, 1 ; exit
    mov ebx, 0
    int 0x80


section.data:
msg1: db "Hello world", 10
msg2: db "Hello world!", 10
len1: equ $-msg1
len2: equ $-msg2

it prints out: Hello world Hello world! but why msg2?

1 Answers

len1 is populated incorrectly, it should be:

section  .rodata        ; space needed between section directive and its operand
                        ; On Linux we normally put read-only data in .rodata

msg1: db "Hello world", 10
len1: equ $-msg1
msg2: db "Hello world!", 10
len2: equ $-msg2

So len1 is a difference between current address ($) and the address of msg1. This way it would be a length of first message.

See How does $ work in NASM, exactly? for more details and examples.


Note that section.data: is just a label defining a symbol name with a dot in the middle. It doesn't switch sections, so your code and data are in the .text section (with read-only + exec permission), which is the default section at the top of the file for nasm -f elf32 outputs.

Use section .data if you want read+write without exec, or section .rodata on Linux if you want read-only without exec, where compilers put string literals and other constants to group them together separate from code.

Related