我正在尝试编写一个程序,该程序获得一个具有一位或两位数的数字,并写入Hello!
次数与该数字相同。
我用这些帖子来编写我的代码:
NASM: The loop turns into an infinite loop
Check null character in assembly language
Multi-Digit Input from NASM我不明白:)
但是我的代码仅适用于两位数字,而一位数字的结果是错误的。
我的代码:
section .data
msg db 'Hello!',0xA
len equ $-msg
section .bss
n resb 2
section .text
global _start
_start:
;get n
mov edx, 2
mov ecx, n
mov ebx, 0
mov eax, 3
int 0x80
lea esi,[n] ;address of our text
call toint
;loop for print 'Hello!\n'
print_loop:
push ecx
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
pop ecx
loop print_loop
mov eax, 1
int 0x80
toint:
push eax
push ebx
xor ebx, ebx
next_digit:
movzx eax, byte[esi]
sub al , '0'
imul ebx, 10
add ebx, eax
inc esi
cmp byte [esi] , 0x0 ;check next character is null or not
jne next_digit
; end_loop:
mov ecx, ebx
pop eax
pop ebx
ret
答案 0 :(得分:1)
sys_read 调用在EAX
中返回发送到输入缓冲区的字符数。因为您允许输入最大2个字符,此计数将为0、1或2。您可以在 toint 例程中使用此信息。
; IN (eax,esi) OUT (ecx)
toint:
mov ecx, eax ; Number of digits
jecxz done
push eax ; (1)
push ebx ; (2)
push esi ; (3)
xor ebx, ebx
next:
movzx eax, byte [esi]
sub al , '0'
imul ebx, 10
add ebx, eax
inc esi
dec ecx
jnz next
mov ecx, ebx
pop esi ; (3)
pop ebx ; (2)
pop eax ; (1)
done:
ret
请注意,在堆栈中保存/恢复寄存器时要遵循相反的顺序! (您的代码错过了这个...)
a。首选MOV
变体来加载地址。总是简短的指令。
b。防止输入零。
C。不要使用LOOP
。这是很慢的指示。
d。提供退出代码以终止程序。
mov esi, n ; (a)
call toint ; -> ECX
jecxz Exit ; (b)
print_loop:
...
dec ecx ; (c)
jnz print_loop
Exit:
xor ebx, ebx ; (d)
mov eax, 1
int 0x80