我在Assembly中的第二个程序出了问题。任务是从键盘读取多行文本并将其写入缓冲区(.comm)。输入空行后,程序应在每个先前键入的文本行的循环中回显。一行文本的限制是100个字符。但是,我得到一个“程序接收信号sigsegv分段错误/ 0x00000000006000a5 in check()”错误信息。
我的想法是创建一个大小为5050字节的缓冲区。每行文本最多可包含100个字符。这是缓冲区的可视化结构:
[First line ][0][Second line ][0][Short ][0][Text ][0]
更新:根据Jester的回复(谢谢!),我稍微修改了我对该程序的想法。我放弃了每行100字节的想法。我只需将它们一个接一个地放置,只需用特殊字符(0)分隔即可。所以缓冲区的新结构是:
[First line of text][0][No matter how long it is][0][short][0]
但是,我在向“add_separator”部分的BUFFER添加特殊的“0”字符时遇到了问题。我还想知道是否真的有必要,因为我们在BUFFER中添加了“\ n”新线路指示器?
此外,当我检查输入的代码行是否为空时,部分永远不会返回true(空行状态),因此程序会继续加载和加载新行。我错过了什么吗?
以下是更新的代码:
SYSEXIT = 1
SYSREAD = 3
SYSWRITE = 4
STDOUT = 1
STDIN = 0
EXIT_SUCCESS = 0
.align 32
.data #data section
.comm BUFFER, 5050 #my buffer of a size of 5050 bytes
BUFFER_len = 5050
.global _start
_start:
mov $0,%esi
read:
mov $SYSREAD, %eax
mov $STDIN, %ebx
mov BUFFER(%esi), %ecx
mov $1, %edx
int $0x80
check:
cmp $0, %eax # check if entered line is empty
je end # if yes, end program
lea BUFFER(%esi), %ecx # move the latest character for comparison
cmp '\n', %ecx # check if it's a line end
inc %esi # increment the iterator
je end
jmp read
end:
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $BUFFER, %ecx
mov $BUFFER_len, %edx
int $0x80
mov $SYSEXIT, %eax
mov $EXIT_SUCCESS, %ebx
int $0x80
提前感谢任何提示!
菲利普
答案 0 :(得分:3)
一些事情:
esp
作为通用注册用作初学者read
系统调用最多会读取您指定的字节数(在本例中为BUFFER_LEN
),它将返回读取的字节数。你应该传入1,所以你可以阅读char-by-char。100
(你的意思是直线,对吧?)并不是非常有用,只是连续追加每个角色,因为这也是你想要打印它们的方式。 / LI>
cmp '\n', %al
会尝试使用'\n'
作为地址,您希望cmp $'\n', %al
立即使用jg
跳过jle
实际上是不必要的,只需保留jle
并让执行继续正常,否则