Accepting and printing two strings in nasm assembly

By : ThisGuy
Source: Stackoverflow.com
Question!

I have this code:

section .data
   msg3 db 'Enter Two Strings: '
   msg3Len equ $ -msg3

section .bss
   string1Len resb 1
   string1 resb 0
   string2Len resb 1
   string2 resb 0

section .text
   global _start

_start:
   mov eax,4
   mov ebx,1
   mov ecx,msg3
   mov edx,msg3Len
   int 80h

   mov eax,3
   mov ebx,1
   mov ecx,string1
   int 80h

   dec al
   mov byte [string1Len], al

   mov eax,3
   mov ebx,1
   mov ecx,string2
   int 80h

   dec al
   mov byte [string2Len], al

   mov eax,4
   mov ebx,1
   mov ecx,string1
   mov edx,[string1Len]
   int 80h

   mov eax,4
   mov ebx,1
   mov ecx,string2
   mov edx,[string2Len]
   int 80h

   mov eax, 0
   mov ebx, 1
   int 80h

I'm having problems in printing two strings. It prints excess and garbage characters. Moreover, when I print three strings, it prints excessive characters. What is wrong with my code when it seems right?

By : ThisGuy


Answers

When you read from stdin to string1 and string2 you're writing to memory that haven't allocated (at least not for that purpose). resb 0 will reserve zero bytes of space (== no space). You should reserve as much space as the size of the longest string you expect to be reading.

Another problem is that you're reading 32 bits from string1Len and string2Len (mov edx,[string1Len]) even though these variables are only one byte in size - which means that you'll be reading 3 bytes beyond the actual variable. Either make the variables dwords (using resd), or use the movzx instruction to zero-extend bytes into dwords (e.g. movzx edx,byte [string1Len]).

By : Michael


As @Michael wrote about using resd or movzx, this is a better work around.

I tested it in Ubuntu 64bit:

; Compile with: nasm -f elf twoString.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 twoString.o -o twoString
; Run with: ./twoString

SECTION .data
msg     db      'Enter Two Strings: ', 0Ah
msgLen equ $ - msg

SECTION .bss
string1:     resb    255
string2:     resb    255

SECTION .text
global  _start

_start:

    ;print msg
    mov     edx, msgLen
    mov     ecx, msg
    mov     ebx, 1
    mov     eax, 4
    int     80h

    mov     edx, 255        ; number of bytes to read
    mov     ecx, string1    ; reserved space to store our input (known as a buffer)
    mov     ebx, 0          ; write to the STDIN file
    mov     eax, 3          ; invoke SYS_READ (kernel opcode 3)
    int     80h

    mov     edx, 255        ; number of bytes to read
    mov     ecx, string2    ; reserved space to store our input (known as a buffer)
    mov     ebx, 0          ; write to the STDIN file
    mov     eax, 3          ; invoke SYS_READ (kernel opcode 3)
    int     80h

    mov     edx, 255
    mov     ecx, string1
    mov     ebx, 1
    mov     eax, 4
    int     80h

    mov     edx, 255
    mov     ecx, string2
    mov     ebx, 1
    mov     eax, 4
    int     80h
    mov     ebx, 0      ; return 0 status on exit - 'No Errors'
    mov     eax, 1      ; invoke SYS_EXIT (kernel opcode 1)
    int     80h
By : SonOfSun


This video can help you solving your question :)
By: admin