Search code examples
stringassemblynasmsasm

Error while entering a large string in NASM


  1. I am using x64 NASM on Linux (Ubuntu 20.04, using Virtual Box)
  2. Also I am using SASM IDE, which contains io64 library built in it (obviously, this library helps with console input/output)
  3. Task, which I am solving for fun, is pretty basic:
  • Input is a string with length <= 100, where all characters are latin letters
  • Output is a string "Hello, {input}!" (without brackets)
  1. This is my code
; NASM, x64, Linux, Ubuntu 20.04

%include "io64.inc"

section .text
global main
main:
        GET_STRING name, 101        ; reading name
        mov rax, 0                  ; initializing counter
        call input_iter             ; processing input
        mov byte [output + rax + 7], '!'        ; this character is needed by condition
        mov byte [output + rax + 8], 0xa
        mov rax, 0                  ; initializing counter
        call output_iter            ; giving output
        jmp end

input_iter: ; one iteration of input loop
        mov byte ch, [name + rax]
        mov byte [output + rax + 7], ch        ; writing one char from name to output
        inc rax
        cmp byte [name + rax], 0x0             ; GET_STRING ends string with 0-code char
        jne input_iter
        ret

output_iter: ; one iteration of output loop
        PRINT_CHAR [output + rax]        ; char given to out
        inc rax
        cmp byte [output + rax], 0xa     ; if char is NUL, iteration stops
        jne output_iter
        ret

end: ; just an end of program

section .data
output db 'Hello, ', 0xa ; here will be all output
name db 0xa              ; temporary storage for input   
  1. And now the problem: When input is 16 characters or longer, program terminates with error. WIth 15 or less charactes all is OK. I dont know why!

PS This is my first question on Stackoverflow ever. And I like field for code, it's very funny


Solution

  • You didn't reserve enough temporary storage for the input/output string.
    name db 0xa defines room for only one byte, and to no effect initializes it with the value 0xa. This value is overwritten by the first letter in GET_STRING name, 101. The next letters are stored to the undefined memory which follows behind the name. Memory allocated for section .data is rounded up, so several bytes may have been allocated behind the name byte and your program by accident works for short input strings. When the string is longer, it will try to access unallocated memory, which leads to segmentation fault.

    Omit , 0xa from output string definition and replace name db 0xa with
    name: times 101 db 0x0a , see repeating Data in NASM
    You can print output together with name as a one concatenated string.