1

I'm attempting to get ahead of my schooling by teaching myself assembly. I created a Hello World that prints the entire string in one go, and as far as I can tell, it works fine:

global _start

section .data
    hello db "Hello World", 0xa

section .text
_start:
    mov eax, 4  ; System call code. 4 = Write
    mov ebx, 1  ; Descriptor to write to. 1 = stdout
    mov ecx, hello  ; String
    mov edx, 12  ; Length of string
    int 0x80  ; System call


    mov eax, 1  ; System call code. 1 = Exit
    mov ebx, 0  ; Exit code
    int 0x80

This prints "Hello World". For kicks though, I decided to try and split the print up, and print "hello" using one system call, then print "world" after as a separate call:

global _start

section .data
    hello db "Hello"
    world db " World", 0xa

section .text
_start:
    mov eax, 4
    mov ebx, 1
    mov ecx, hello  ; First half
    mov edx, 5  ; First half length
    int 0x80

    mov ecx, world  ; Second half
    mov edx, 7  ; Second half length
    int 0x80


    mov eax, 1
    mov ebx, 0
    int 0x80

Unfortunately though, this only prints "Hello". It seems like it's outright skipping the second interrupt. Playing around with it, I found that if I make the length argument large enough to accommodate the entirety of both strings, it "works":

. . .
mov eax, 4
mov ebx, 1
mov ecx, hello
mov edx, 12  ; Large enough for both strings
int 0x80

mov ecx, world
mov edx, 0
int 0x80
. . .

This correctly prints "Hello World". If I run this in gdb, I can see that in this case, the first system call prints the entire string; it isn't divided. I'm guessing this is because the strings are stored next to each other in memory, and I'm overflowing from hello into world.

Why can't I have two separate write system calls to print two separate strings in this case though?


Running on ParrotOS, in VMWare.

Assembled and linked using:

nasm -f elf64 -g -F dwarf helloWorld.asm
ld -m elf_x86_64 helloWorld.o

First chunk of lscpu:

Architecture:                    x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   43 bits physical, 48 bits virtual
CPU(s):                          4
On-line CPU(s) list:             0-3
Thread(s) per core:              1
Core(s) per socket:              2
Socket(s):                       2
NUMA node(s):                    1
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           142
Model name:                      Intel(R) Core(TM) i5-8365U CPU @ 1.60GHz
. . .
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Carcigenicate
  • 43,494
  • 9
  • 68
  • 117

0 Answers0