我正在编写这个小程序,你输入一个被除数和一个除数,程序将输出商和余数。这是代码:
segment .data
prompt db "Please enter a number: ", 10
promptLen equ $-prompt
prompt2 db "Please enter the divisor: ", 10
prompt2Len equ $-prompt2
prompt3 db "Your quotient is: ",10
prompt3Len equ $-prompt3
prompt4 db "Your remainder is: ",10
prompt4Len equ $-prompt4
segment .bss
inputNum resb 2
inputDiv resb 2
quotient resb 2
remainder resb 2
segment .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, prompt
mov edx, promptLen
int 80h
mov eax, 3
mov ebx, 0
mov ecx, inputNum
mov edx, 2
int 80h
mov eax, 4
mov ebx, 1
mov ecx, prompt2
mov edx, prompt2Len
int 80h
mov eax, 3
mov ebx, 0
mov ecx, inputDiv
mov edx, 2
int 80h
xor edx, edx
mov ax, [inputNum]
mov bx, [inputDiv]
and ax, 0xff
and bx, 0xff
sub ax, '0'
sub bx, '0'
div bx
add ax, '0'
add dx, '0'
mov [quotient], ax
mov [remainder], dx
mov eax, 4
mov ebx, 1
mov ecx, prompt3
mov edx, prompt3Len
int 80h
mov eax, 4
mov ebx, 1
mov ecx, quotient
mov edx, 2
int 80h
mov eax, 4
mov ebx, 1
mov ecx, prompt4
mov edx, prompt4Len
int 80h
mov eax, 4
mov ebx, 1
mov ecx, remainder
mov edx, 2
int 80h
jmp exit
exit:
mov eax, 1
xor ebx, ebx
int 80h
现在代码的方式,我只能处理一个字符的数字;通过减去'0'并将其重新添加到输出中。 任何人都可以帮我使用更有效的方式进行这种转换,这样我就不会只限制一个字符的数字吗?
答案 0 :(得分:0)
不检查输入和错误:
segment .data
prompt db "Please enter a number: "
promptLen equ $-prompt
prompt2 db "Please enter the divisor: "
prompt2Len equ $-prompt2
prompt3 db 10, "Your quotient is: "
prompt3Len equ $-prompt3
prompt4 db 10, "Your remainder is: "
prompt4Len equ $-prompt4
linefeed db 10
segment .bss
inputNum resb 80
inputDiv resb 80
uNum resd 1
uDiv resd 1
uQuo resd 1
uRem resd 1
quotient resb 80
quotientLen resd 1
remainder resb 80
remainderLen resd 1
segment .text
global _start
dec2eax: ; Arg ESI: ASCII-string (0x0A-terminated) with decimal digits
xor eax,eax ; Result
xor edx, edx ; Especially to clear the 32-bit-part of EDX
.loop:
mov dl, byte [esi] ; Read digit
cmp dl, 10 ; End of string (SYS_READ - in certain cases not existent)?
je .finish ; Yes: done
lea eax, [eax*4+eax] ; EAX = 5 * EAX ...
add eax, eax ; ... and EAX = 2 * EAX results in EAX = EAX * 10
add esi, 1 ; Increment pointer to string
and dl, 0x0F ; Eliminate ASCII part of digit
add eax, edx ; Add digit to result
jmp .loop ; Next character
.finish:
ret ; Result: Converted unsigned integer in EAX
eax2dec: ; Arg EDI: Pointer to string that gets ASCII-characters
mov ebx, 10 ; Divisor
xor ecx, ecx ; CX=0 (number of digits)
.first_loop:
xor edx, edx ; Attention: DIV applies also DX!
div ebx ; DX:AX / BX = AX remainder: DX
push dx ; LIFO
inc cl ; Increment number of digits
test eax, eax ; AX = 0?
jnz .first_loop ; No: once more
mov ebx, ecx ; Save strlen
.second_loop:
pop ax ; Get back pushed digit
or al, 00110000b ; AL to ASCII
mov byte [edi], al ; Save AL
inc edi ; DI points to next character in string DECIMAL
loop .second_loop ; Until there are no digits left
mov byte [edi], 0 ; End-of-string delimiter (ASCIZ)
mov eax, ebx ; Return strlen in EAX
ret
_start:
mov eax, 4
mov ebx, 1
mov ecx, prompt
mov edx, promptLen
int 80h
mov eax, 3
mov ebx, 0
mov ecx, inputNum
mov edx, 80
int 80h
mov eax, 4
mov ebx, 1
mov ecx, prompt2
mov edx, prompt2Len
int 80h
mov eax, 3
mov ebx, 0
mov ecx, inputDiv
mov edx, 80
int 80h
mov esi, inputNum
call dec2eax
mov [uNum], eax
mov esi, inputDiv
call dec2eax
mov [uDiv], eax
xor edx, edx
mov eax, [uNum]
mov ebx, [uDiv]
div ebx
mov [uQuo], eax
mov [uRem], edx
mov eax, [uQuo]
mov edi, quotient
call eax2dec
mov [quotientLen], eax
mov eax, [uRem]
mov edi, remainder
call eax2dec
mov [remainderLen], eax
mov eax, 4
mov ebx, 1
mov ecx, prompt3
mov edx, prompt3Len
int 80h
mov eax, 4
mov ebx, 1
mov ecx, quotient
mov edx, [quotientLen]
int 80h
mov eax, 4
mov ebx, 1
mov ecx, prompt4
mov edx, prompt4Len
int 80h
mov eax, 4
mov ebx, 1
mov ecx, remainder
mov edx, [remainderLen]
int 80h
mov eax, 4
mov ebx, 1
mov ecx, linefeed
mov edx, 1
int 80h
jmp exit
exit:
mov eax, 1
xor ebx, ebx
int 80h