在你的最后一个问题中,你显示message
为一个以零结尾的字符串,所以cmp al, 0
将指示字符串的结尾。sys_read 不会创建以零结尾的字符串!(如果需要,我们可以在其中填充一个零 - 例如作为 sys_open 的文件名) sys_read 将读取最多 edx 字符。当且仅当按下“enter”键时,来自标准输入的 sys_read 才会返回。如果输入的 edx 字符少于 edx 字符,则字符串以换行字符(十进制 10 或 0xA 或 0Ah 十六进制)终止 - 您可以查找...但是,如果讨厌的用户键入的 edx 字符以上,则只有 edx 字符可以进入你的缓冲区,“多余的”保留在操作系统的缓冲区中(以后可能会造成麻烦!)。在这种情况下,您的字符串不会以换行符终止,因此查找它会失败。sys_read 返回实际读取的字符数 - 直到 edx - 包括换行 - 在 eax 中。如果你不
作为一个实验,在 edx 中使用一些小数字(比如 4)执行 sys_read,然后退出程序。键入“abcdls”(回车)并观察“ls”的执行情况。如果某个小丑输入“abcdrm -rf .”......好吧,不要!
最安全的事情是刷新操作系统的输入缓冲区。
mov ecx, num
mov edx, len
mov ebx, 1
mov eax, 3
int 80h
cmp byte [ecx + eax - 1], 10 ; got linefeed?
push eax ; save read length - doesn't alter flags
je good
flush:
mov ecx, dummy_buf
mov edx, 1
mov ebx, 1
mov eax, 3
int 80h
cmp byte [ecx], 10
jne flush
good:
pop eax ; restore length from first sys_read
我们可以将它放在堆栈中,而不是在 .bss(或 .data)中定义dummy_buf
- 在这里尽量保持简单。这是不完美的——我们不知道我们的字符串是否以换行符结尾,并且我们不检查错误(不太可能从标准输入读取)。你会发现你正在编写更多的代码来处理错误和“白痴用户”输入,而不是“做工作”。不可避免的!(这是一种低级语言——我们必须告诉 CPU 每一件事!)
sys_write 也不知道以零结尾的字符串!它会打印 edx 字符,不管有多少垃圾。您想弄清楚您实际要打印多少个字符,并将其放入 edx 中(这就是我保存/恢复上面原始长度的原因)。
您提到“整数”并num
用作变量名。除了 ascii 代码之外,这些函数都不知道“数字”。您正在阅读和书写字符。将一位数转换为字符很容易 - 添加或减去“0”(十进制 48 或 30h)。多位数字更复杂 - 看看一个例子,如果这是你需要的。
最好的,弗兰克