问题描述
- 我在 Linux(Ubuntu 20.04,使用 Virtual Box)上使用 x64 NASM
- 我还使用了 SASM IDE,其中包含内置的 io64 库(显然,该库有助于控制台输入/输出)
- 我为了好玩而解决的任务非常基本:
- 这是我的代码
; 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
- 现在的问题是: 当输入为 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
您可以将 output
与 name
一起打印为一个串联字符串。