section .text
global _start
_start:
xor esi,esi
_ccout:
cmp esi,10
jnl _end
inc esi
mov eax,4
mov ebx,1
mov ecx,esi
mov edx,2
int 80h
jmp _ccout
_end:
mov eax,1
int 80h
section .data
答案 0 :(得分:0)
好吧,循环正常,但你没有正确使用系统调用。这里涉及一些神奇的数字,所以让我们首先解决这个问题:
write
到目前为止,这么好。 write
需要一个文件描述符,缓冲区的地址以及该缓冲区的长度或它应该写入文件描述符的部分。所以,这看起来的方式类似于
mov eax,4 ; write syscall
mov ebx,1 ; stdout
mov ecx,somewhere_in_memory ; buffer
mov edx,1 ; one byte at a time
将其与您的代码进行比较:
mov eax,4
mov ebx,1
mov ecx,esi ; <-- particularly here
mov edx,2
int 80h
你在那里做什么(除了传递错误的长度)是将esi
的内容传递给write
作为内存地址,从中读取它应该写的东西到stdout。通过纯粹的偶然事件,这不会崩溃,但在内存中的那个位置没有有用的数据。
为了解决这个问题,您需要在内存中放置一个位置。此外,由于write
适用于字符而不是数字,因此您必须通过添加“0”来自行处理格式化问题。 (ASCII为48)。总而言之,它可能看起来像这样:
section .data
text db 0 ; text is a byte in memory
section .text
global _start
_start:
xor esi,esi
_ccout:
cmp esi,10
jnl _end
inc esi
lea eax,['0'+esi] ; print '0' + esi. lea == load effective address
mov [text],al ; is useful here even though we're not really working on addresses
mov eax,4 ; write
mov ebx,1 ; to fd 1 (stdout)
mov ecx,text ; from address text
mov edx,1 ; 1 byte
int 80h
jmp _ccout
_end:
mov [text],byte 10 ; 10 == newline
mov eax,4 ; write that
mov ebx,1 ; like before.
mov ecx,text
mov edx,1
int 80h
mov eax,1
mov ebx,0
int 80h
输出123456789:
可能不是您想要的,但您应该可以从此处获取。为读者和所有这些练习。