1

我正在尝试编写一个允许我打印多个字符(字符串或整数)的程序。我遇到的问题是我的代码只打印一个字符,然后换行并保持在无限循环中。这是我的代码:

SECTION .data
len EQU 32
SECTION .bss
num resb len
output resb len

SECTION .text
GLOBAL _start
_start:
Read:
    mov eax, 3
    mov ebx, 1
    mov ecx, num
    mov edx, len
    int 80h

Point:
    mov ecx, num

Print:
    mov al, [ecx]
    inc ecx
    mov [output], al

    mov eax, 4
    mov ebx, 1
    mov ecx, output
    mov edx, len
    int 80h

    cmp al, 0
    jz Exit

Clear:
    mov eax, 0
    mov [output], eax
    jmp Print  

Exit:
    mov eax, 1
    mov ebx, 0
    int 80h 

有人可以指出我做错了什么吗?

谢谢,

赖莱

4

2 回答 2

2

在您第一次进入该Print部分时,ecx是指向字符串的开头并且您使用它将单个字符复制到输出字符串的开头。但是再写几条指令,您ecx用指向输出字符串的指针覆盖,并且永远不会恢复它,因此您永远无法复制和打印字符串的其余部分。

另外,您为什么要write()使用单个字符串调用以循环遍历它以打印整个字符串?为什么不直接传入num而不是将单个字符复制到output并传递呢?

于 2012-10-25T12:01:17.337 回答
1

在你的最后一个问题中,你显示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)。多位数字更复杂 - 看看一个例子,如果这是你需要的。

最好的,弗兰克

于 2012-10-25T20:06:48.680 回答