在 NASM 中输入大字符串时出错

问题描述

  1. 我在 Linux(Ubuntu 20.04,使用 Virtual Box)上使用 x64 NASM
  2. 我还使用了 SASM IDE,其中包含内置的 io64 库(显然,该库有助于控制台输入/输出
  3. 我为了好玩而解决的任务非常基本:
  • 输入是一个长度
  • 输出一个字符串“你好,{输入}!” (不带括号)
  1. 这是我的代码
; 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. 现在的问题是: 当输入为 16 个字符或更长时,程序会因错误而终止。使用 15 个或更少的字符就可以了。 我不知道为什么!

附注 这是我关于 Stackoverflow 的第一个问题。我喜欢代码字段,这很有趣

解决方法

您没有为输入/输出字符串预留足够的临时存储空间。
name db 0xa 只定义了一个字节的空间,并且用值 0xa 初始化它没有任何效果。该值被 GET_STRING name,101 中的第一个字母覆盖。 下一个字母存储在 name 后面的未定义内存中。 为部分 .data 分配的内存被四舍五入,因此可能在 name 字节后面分配了几个字节,并且您的程序意外地适用于短输入字符串。当字符串较长时,它会尝试访问未分配的内存,从而导致分段错误。

,0xa 字符串定义中省略 output 并将 name db 0xa 替换为
name: times 101 db 0x0a ,见 repeating Data in NASM
您可以将 outputname 一起打印为一个串联字符串。