对于NASM中的多个字符,ASCII到十进制,反之亦然

时间:2014-10-20 15:56:59

标签: assembly ascii nasm data-conversion

我正在编写这个小程序,你输入一个被除数和一个除数,程序将输出商和余数。这是代码:

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'并将其重新添加到输出中。 任何人都可以帮我使用更有效的方式进行这种转换,这样我就不会只限制一个字符的数字吗?

1 个答案:

答案 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