0
  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

walotian
  • 3
  • 1
  • 1
    1. did you reserve enough storage for the input string? 2. error messages are usually very detailed, what with numbers and things. if you're getting an error and you want our help with it then share the detail. – Erik Eidt May 10 '21 at 16:05
  • 1. Reserve storage? I just write characters directly to memory. Maybe this way is wrong, but I dont know another since I am newbie to assembly language 2. In this very case SASM does not return any details about error, just says that program terminated abnormally. But I can say, this is runtime error dependent on input value. I don't know even line which causes error... – walotian May 10 '21 at 16:09
  • Use a debugger: which instruction faults? (Assuming that's the "error" you mention but didn't quote). A [mcve] needs to include the exact error, if there is one. – Peter Cordes May 10 '21 at 16:11
  • I have used debugger and found line, where error occurs: PRINT_CHAR [output + rax] ; char given to out. And exact error text: Program received signal SIGSEGV, Segmentation fault – walotian May 10 '21 at 16:20
  • 2
    @walotian You cannot just write text into a random memory area. You need to first allocate sufficient memory and then write to the allocated region. – fuz May 10 '21 at 16:34

1 Answers1

2

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.

vitsoft
  • 5,515
  • 1
  • 18
  • 31
  • 1
    Specifically, memory protection happens with page granularity (4096 bytes). That's where the "rounding up" happens, because the linker doesn't usually put your `.data` section right at the end of a page. – Peter Cordes May 10 '21 at 18:44
  • Thanks, that worked! But somehow program now works with strings which contains even 200 characters... I dont know how, I though that GET_STRING would not work at all with strings bigger than second argument... – walotian May 10 '21 at 19:20