NASM-如何将整数输入转换为二进制ASCII码?

时间:2018-12-15 23:58:20

标签: assembly x86 nasm

我一直在尝试将输入整数转换为二进制ASCII码,但是我不知道该怎么做。我做一个len函数来知道输入的大小,知道何时停止。该代码的主要思想是将123之类的数字转换为00110001 00110010 00110011之类的ASCII代码。 我想制作类似于此页面https://www.traductorbinario.com/#ascii的内容,但要使用整数输入。 这是我目前所拥有的:

%include  "io.mac"

.DATA
msg_binary db "Text in binary",0

.UDATA
number resd 1

.CODE
    .STARTUP
        GetLInt [number]
        mov EAX, [number]
        mov EBX, 10
    len:
        inc ECX
        div EBX
        xor EDX, EDX
        cmp EAX, 0
        jne len

        PutStr    msg_binary
        nwln
        mov     EBX, ECX
        sub     ECX, ECX
        mov     ESI, number
    repeat:  
        mov     AL,[ESI]
        mov     AH,80H
        mov     ECX,8        ; loop count to print 8 bits
    print_bit:
        test    AL,AH        ; test does not modify AL
        jz      print_0    ; if tested bit is 0, print it
        PutCh   '1'          ; otherwise, print 1
        jmp     skip1
    print_0:
        PutCh   '0'          ; print 0
    skip1:
        shr     AH,1         ; right-shift mask bit to test
        loop    print_bit
        PutCh   ' '
        inc     ESI
        dec     EBX
        cmp     EBX, 0
        jne     repeat
        nwln
   .EXIT

1 个答案:

答案 0 :(得分:0)

我假设您在Linux上使用Dandamudi的io.mac

表B.1 io.mac中定义的I / O例程摘要

Name    Operand(s)                  Operand location    Size        What it does
PutCh   source                      value               8 bits      Displays the character
                                    register                        located at source
                                    memory

GetCh   destination                 register            8 bits      Reads a character into
                                    memory                          destination

nwln    none                        —                   —           Displays a carriage return
                                                                    and line feed

PutStr  source                      memory              variable    Displays the NULL-terminated
                                                                    string at source

GetStr  destination [,buffer size]  memory              variable    Reads a carriage-return-terminated
                                                                    string into destination and stores it
                                                                    as a NULL-terminated string.
                                                                    Maximum string length is
                                                                    buffer size-1.

PutInt  source                      register            16 bits     Displays the signed 16-bit number
                                    memory                          located at source

GetInt  destination                 register            16 bits     Reads a signed 16-bit number into
                                    memory                          destination

PutLint source                      register            32 bits     Displays the signed 32-bit number
                                    memory                          located at source

GetLint destination                 register            32 bits     Reads a signed 32-bit number into
                                    memory                          destination

(from: Dandamudi, Sivarama P., Introduction to Assembly Language Programming, 2nd ed. 2004)

出于您的目的,您必须首先将GetLInt的32位整数转换为十进制ASCII字符串。然后,您可以将单个字符转换为二进制字符串。

下面的程序使用一个过程来执行第一次转换。注意Dandamudi的.EXIT不在源代码的末尾,而是程序返回shell的位置。此外,我不同意Dandamudi使用TEST将字符链接到可变掩码的方法。每个SHL八次隔离一位比较容易。

%include  "io.mac"

.DATA
msg_binary db "Text in binary",0

.UDATA
number  resd 1
decimal resb 11                 ; Max. ten digits plus one NULL

.CODE
    .STARTUP
        GetLInt [number]        ; Input & convert input to 32-bit integer
        PutStr msg_binary
        nwln

        mov eax, [number]       ; Value of number
        mov edi, decimal        ; Offset of decimal
        call int2str            ; Convert number to decimal

        mov esi, decimal        ; Offset of decimal
    repeat:
        mov al, [esi]           ; Load a character
        cmp al, 0               ; End of string?
        je done                 ; Yes -> end of repeart
        mov ecx, 8              ; Loop eight times
    loop1:
        shl al, 1               ; Isolate the leftmost bit and shift the rest to the left
        jnc print_0             ; if tested bit is 0, print it
        PutCh '1'               ; otherwise, print 1
        jmp skip1
    print_0:
        PutCh '0'               ; print 0
    skip1:
        loop loop1              ; Loop and decrement ECX
        PutCh ' '
        add esi, 1              ; Offset of next character
        jmp repeat              ; Once more

    done:
        nwln                    ; New line
    .EXIT                       ; Return to shell

int2str:    ; Converts an positive integer in EAX to a string pointed to by EDI
    xor ecx, ecx
    mov ebx, 10
    .LL1:                       ; First loop: Collect the remainders
    xor edx, edx                ; Clear EDX for div
    div ebx                     ; EDX:EAX/EBX -> EAX Remainder EDX
    push dx                     ; Save remainder
    inc ecx                     ; Increment push counter
    test eax, eax               ; Anything left to divide?
    jnz .LL1                    ; Yes: loop once more

    .LL2:                       ; Second loop: Retrieve the remainders
    pop dx                      ; In DL is the value
    or dl, '0'                  ; To ASCII
    mov [edi], dl               ; Save it to the string
    inc edi                     ; Increment the pointer to the string
    loop .LL2                   ; Loop ECX times

    mov byte [edi], 0           ; Termination character
    ret                         ; RET: EDI points to the terminating NULL