Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
linux nasm打印多个字符_Linux_Assembly_X86_Nasm - Fatal编程技术网

linux nasm打印多个字符

linux nasm打印多个字符,linux,assembly,x86,nasm,Linux,Assembly,X86,Nasm,我试图写一个程序,将允许我打印多个字符(字符串或整数)。我遇到的问题是,我的代码只打印其中一个字符,然后换行,并停留在无限循环中。这是我的密码: 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

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

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 
有人能指出我做错了什么吗

谢谢


Rileyh

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


另外,为什么要用一个字符串调用
write()
,目的是循环打印整个字符串?为什么不直接传入
num
,而不是将单个字符复制到
输出
并传递它?

在上一个问题中,您将
消息
显示为以零结尾的字符串,因此
cmp al,0
将指示字符串的结尾。sys_read不会创建以零结尾的字符串!(如果需要,我们可以在其中填充一个零-例如,作为sys_open的文件名)sys_read将读取最多edx个字符。当且仅当按下“回车”键时,从stdin读取的sys_才会返回。如果输入的字符少于edx,字符串将以换行字符(10十进制或0xA或0Ah十六进制)终止-您可以查找该字符。。。但是,如果烦人的用户键入的edx字符多于edx字符,则只有edx字符进入缓冲区,“多余”字符仍保留在操作系统的缓冲区中(以后可能会造成麻烦!)。在这种情况下,字符串不是以换行符结尾的,因此查找它将失败。sys_read返回实际读取到edx的字符数,包括eax中的换行符。如果不希望在长度中包含换行符,可以减小eax

作为实验,在edx中用一些小数字(比如4)进行系统读取,然后退出程序。键入“abcdls”(回车)并观察“ls”的执行情况。如果某个小丑键入“abcdrm-rf”。。。好吧,不要

最安全的方法是刷新操作系统的输入缓冲区。

我们不需要在.bss(或.data)中定义
dummy\u buf
,而可以将其放在堆栈中—尽量保持简单。这是不完美的——我们不知道字符串是否以换行符终止,也不检查错误(不太可能从stdin读取)。您会发现,您编写的处理错误和“白痴用户”输入的代码比“完成工作”要多得多。不可避免!(这是一种低级语言——我们必须告诉CPU每一件事!)

sys_write也不知道以零结尾的字符串!它将打印edx字符,不管有多少垃圾。您需要计算出实际要打印的字符数,并将其放入edx(这就是我保存/恢复上述原始长度的原因)

您提到“整数”并使用
num
作为变量名。除了ascii码之外,这两个函数都不知道“数字”。你在读和写人物。将一个数字转换成一个字符是很容易的-加或减“0”(48位小数或30小时)。多个数字更为复杂——如果您需要的话,请查看周围的示例

最好的,
Frank

此外,应该使用
读取
系统调用的返回值来确定实际放入缓冲区的字节数。
    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