NASM将二进制数转换为十进制数

时间:2015-06-16 10:24:10

标签: assembly x86 nasm

%include "asm_io.inc"

segment .data
msg1 db "Enter a number: ",0
msg2 db "Bad Number! try again. ",0
msg3 db "Enter Decimal value is: ",0

segment .bss
mask resd 1

segment .text
global main

main:
    enter 0,0
    pusha

    mov dword[mask],1
    mov esi,10
    mov ebx,0


input:
    mov eax,msg1
    call print_string
    call read_int
    mov ecx,eax

next:
    cmp eax,0
    je cont
    mov edx,0   
    div esi
    cmp edx,1
    ja error
    jmp next

error:      
    mov eax,msg2
    call print_string
    call print_nl
    jmp input


cont: mov eax,ecx

convert:
    cmp eax,0
    je sof
    mov edx,0
    div esi
    cmp edx,0
    je shift_1
    or ebx,[mask]

shift_1:    
    shl dword[mask],1
    jmp convert

sof:    
    mov eax,msg3
    call print_string
    mov eax,ebx
    call print_int
    call print_nl

    popa 
    leave 
    ret

程序只获得1和0并打印其十进制值。 它不能超过10位数(我需要它在32位数上工作),它也不适用于以0开头的数字(如011) 帮助请:)

1 个答案:

答案 0 :(得分:1)

我不知道read_int究竟做了什么,但如果它被相应命名,它应该从输入读取一个32位整数并在EAX中返回。
这意味着您要求用户输入二进制数作为十进制数字,以获得32位数字,您需要32位十进制数字,因此数量级别为10 ^ 32或更多或更少106位。 / p>

所以这显然不是可行的方法。您需要一次读取一个二进制数字,char为char。这种方式从二进制数字转换为数字更加容易,因为您只需要进行一些移位!

似乎你想要做的只是从二进制数字转换为数字(即用户输入二进制数,你想要它的32位值),因为print_int函数完成转换工作一个十进制数字的数字(即打印十进制的32位值)。

这是NASM中的示例程序(与GCC链接),可以满足您的需求。您只需要get_bin功能。这使用C库函数,但方式类似于库例程。它还包括一个以十进制打印32位值的例程,您可以跳过它 使用get_bin中的代码作为参考。

BITS 32

GLOBAL _main

EXTERN _getchar
EXTERN _printf

SECTION .data

strInput    db "Input a binary number: ", 0
strInputErr db "Binary number not valid!",0ah, 0
strChar     db "%c", 0h

SECTION .text

_main:

    push strInput
    call _printf 
    add esp, 04h

    call get_bin 
    jnc .input_error

    push eax
    call show_dec

.end:
    ret 

.input_error:
    push strInputErr
    call _printf 
    add esp, 04h

jmp .end 




get_bin:
    push ecx
    push edx

    mov ecx, 20h    ;//32 bit

    xor edx, edx    ;Temp result

.get:
    push edx 
    call _getchar
    pop edx

    cmp al, 0ah
    je .return      ;End early if user press Return

    sub al, 30h     ;ASCII digit -> digit value
    cmp al, 01h     ;Only 0 and 1 allowed
    ja .end         ;Here CF=0, meaning conversion failed

    shr al, 01h     ;Set the CF based on the new digit
    rcl edx, 01h    ;Shift this digit into EDX from the right
loop .get

.return:
    mov eax, edx    ;Return in EAX
    stc             ;CF=1 means conversion ok

.end:
    pop edx
    pop ecx
    ret

;number     
show_dec:
    push ebp
    mov ebp, esp

    pushad

    sub esp, 04h 
    mov BYTE [ebp-04h], 0 

    mov ebx, 1000000000d 
    mov eax, DWORD [ebp+08h]
    mov ecx, 10d 

.loop:
    xor edx, edx
    div ebx 

    test al, al
    setnz ah 
    or BYTE [ebp-04h], ah
    setnz ah 
    test cl, cl
    setz ch
    or ch, ah
    jz .continue

    add eax, 30h 

    pushad
    push eax
    push strChar
    call _printf
    add esp, 08h 
    popad 

.continue:
    xor ch, ch 
    mov eax, edx 
    push eax

    mov eax, ebx
    xor edx, edx
    mov ebx, 10d
    div ebx
    mov ebx, eax 
    pop eax
loop .loop

    add esp, 04h 

    popad 

    pop ebp
    ret 04h

请注意,默认情况下,终端/控制台的输入已经完成。