我有一个汇编程序,可以像这样在一行中打印出 1 - 9 的数字:123456789。我想要的是将这些值分别打印在一行上;每行一个数字。
我尝试实现新行,但在我的代码中抛出错误 Segmentation fault (core dumped)。我对组装还很陌生,所以我真的不知道如何找出为什么这不起作用。它只打印第一个数字 (1),然后抛出该错误。
我尝试换行的代码:
mov dl, 13
mov ah, 02h
int 21h
mov dl, 10
mov ah, 02h
int 21h
我的代码:
_start:
mov ecx, 10
mov eax, '1'
L1:
mov [num], eax
mov eax, 4
mov ebx, 1
push ecx
mov ecx, num
mov edx, 1
int 0x80
mov eax, [num]
sub eax, '0'
inc eax
add eax, '0'
pop ecx
loop L1
mov eax, 1
int 0x80
section .bss
num resb 1
最佳答案
您应该使用与打印数字相同的系统调用来打印换行符。
此外,Linux 中的换行符只是 LF(字符 10,)而不是 CR(字符 13)后跟 LF,就像 Windows/DOS 使用的那样。
如何在 Linux 上以 x86 汇编打印到标准输出
This answer描述每个参数对 Linux 打印系统调用的作用,这就是您通过引发 int 0x80
调用的内容。
系统调用使用寄存器来传递参数。从链接的答案中,eax
是系统调用号(4 = 打印),ebx
是目标流(1 = stdout),ecx
是指向要打印的数据的指针,edx是要打印的数据的长度。
因此,在您的循环中实际执行打印的代码是:
mov [num], eax ; Moves the character in eax to the buffer pointed to by num.
mov eax, 4 ; Moves 4 into eax, i.e. selects the print system call.
mov ebx, 1 ; Moves 1 into ebx, i.e. selects stdout as the destination.
mov ecx, num ; Moves the address where your text is stored into ecx.
mov edx, 1 ; Moves the number of bytes to characters (1) into edx.
int 0x80 ; Executes a Linux system call using the above parameters.
要打印换行符,您只需要在 eax
中在此代码之前添加换行符(十进制字符 10),而不是数字字符。因此,例如,在此代码之前添加 mov eax, 10
将打印换行而不是数字。
如何使它与您现有的循环一起工作
“我的代码”部分中的num
是您存储要打印的数据的缓冲区。但是,此代码也使用此内存来跟踪它打印的最后一个数字。因此,有两种方法可以避免在循环之间丢失该信息:
选项 1:只需将缓冲区的大小从 1 个字节增加到 2 个字节,然后将换行符放在第二个字节中。然后你可以将 2
移动到 edx
而不是 1
来告诉 Linux 你想要打印 2 个字符,从而打印两个数字以及每次循环迭代时的换行符。
选项 2:分配另一个单字节缓冲区来存储换行符。将换行符移到那里,然后在系统调用之后进行第二个系统调用,该系统调用会在循环中打印数字以打印换行符。例如,如果您的新缓冲区被称为“lfbuffer”,那么您将在现有循环中的 int 0x80
行之后添加此代码:
mov byte [lfbuffer], 10 ; Moves the a line feed to the buffer pointed to by lfbuffer.
mov eax, 4 ; Moves 4 into eax, i.e. selects the print system call.
mov ebx, 1 ; Moves 1 into ebx, i.e. selects stdout as the destination.
mov ecx, lfbuffer ; Moves the address where your line feed is stored into ecx.
mov edx, 1 ; Moves the number of bytes to characters (1) into edx.
int 0x80 ; Executes a Linux system call using the above parameters.
关于linux - 如何在 x86 程序集中循环打印一个数字后的新行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58427656/