0

I’m new to x_86 assembly language, and trying write some simple stuff to the console.

When I try this:

    section .data
        str: db "0000", 0xA
        len: db 5

    global _start

    section .text
    _start:
        ; system call to print the string
        mov eax, 4  ; "write" system call
        mov ebx, 1  ; Indicates to write to standard out
        mov ecx, str    ; The string
        mov edx, [len]  ; The length of the string
        int 0x80

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

It works fine, and prints out “0000”. But if I then try this:

    section .data
        str: db "0000", 0xA
        len: db 5
        otherStr: db "1111", 0xA
        otherLen: db 5

    global _start

    section .text
    _start:
        ; system call to print the string
        mov eax, 4  ; "write" system call
        mov ebx, 1  ; Indicates to write to standard out
        mov ecx, str    ; The string
        mov edx, [len]  ; The length of the string
        int 0x80

        ; system call to print the string
        mov eax, 4  ; "write" system call
        mov ebx, 1  ; Indicates to write to standard out
        mov ecx, otherStr   ; The string
        mov edx, [otherLen]     ; The length of the string
        int 0x80

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

It outputs all this gobblygook:

    0000
    1111
        
    (#
    /
        6
        sha.asmstrlenotherStrotherLen__bss_start_edata_end.symtab.strtab.shstrtab.text.dat:! 
                                                                                                    ;!'1111

The output I’m expecting is just:

0000

1111

What am I doing wrong here? This is on Fedora Linux and using the NASM assembler. The commands I’m using to link and assemble are these:

nasm -f elf32 example.asm -o ex1.o
ld -m elf_i386 ex1.o -o ex1

1 Answers1

3

len is defined like this

len: db 5

By itself that's fine.

It's loaded like this:

mov edx, [len]

By itself that's also fine.

But together they're wrong. The load loads a DWORD, and there's only one byte dedicated to the variable, so 3 extra bytes are loaded that are "something else". In the first program, they're zeroes from the "zero fill" to pad out the data section to a multiple of the page size. In the second program, they're not zero.

You could make the lengths (both of them) DWORD (eg len: dd 5) or load them with zero-extension eg movzx edx, byte [len].

harold
  • 61,398
  • 6
  • 86
  • 164
  • 1
    Or better, use `str_len equ $ - len` and `mov edx, str_len` instead of loading a constant from memory. [How does $ work in NASM, exactly?](https://stackoverflow.com/q/47494744) – Peter Cordes Jun 08 '23 at 18:51