【问题标题】:Converting a 16-bit decimal number to other bases using NASM assembly使用 NASM 汇编将 16 位十进制数转换为其他基数
【发布时间】:2015-04-27 01:03:59
【问题描述】:

我在使用 NASM 程序集实现正确的十进制到二进制、八进制和十六进制转换时遇到了一些问题。我的大部分代码如下,我知道有一些我仍在努力解决的问题。我已经在代码中注释了相关信息。

    %include "io.mac"
    .STACK 100H
    .DATA
    msg1        db "Please enter a positive integer (max 16 bits): ",0
    msg2        db "The binary (base-2) representation of the number is: ",0
    msg3        db "The octal (base-8) representation of the number is: ",0
    msg4        db "The hex (base-16) representation of the number is: ",0
    msg5        db "A",0 ;These will be implemented when I get the 
    msg6        db "B",0 ;hexadecimal loop working to change 10, 11, 
    msg7        db "C",0 ;etc. to their hex equivalents.
    msg8        db "D",0
    msg9        db "E",0
    msg10       db "F",0

    .UDATA
    num1            resw 1
    quotient        resw 1
    remainder       resw 1

    .CODE
    .STARTUP
    PutStr msg1
    nwln
    GetInt [num1]

    nwln
    PutStr msg2
    nwln
    mov AX, [num1]      
    sub BH, BH

    binary_loop:
    push AX 
    mov BH, byte 2 
    div BH ;All loops output the remainders in reverse order at the moment.
    mov [remainder], AH ;I was thinking of maybe moving the remainder value
    PutInt [remainder] ;to a stack then calling it at the end of the loop,
    mov [quotient], AL ;when the quotient value is zero. However,  
    mov AX, [quotient] ;I do not know enough to make that work. Any help
    cmp [quotient], byte 0 ;would be greatly appreciated
    jz binary_done ;Could also be je, as both do the same thing
    loop binary_loop

    binary_done:
    nwln
    PutStr msg3
    nwln
    mov AX, [num1]
    sub BH, BH      

    octal_loop:     
    push AX
    mov BH, byte 8
    div BH
    mov [remainder], AH
    PutInt [remainder]
    mov [quotient], AL
    mov AX, [quotient]
    cmp [quotient], byte 0
    jz octal_done
    loop octal_loop

    octal_done:
    nwln
    PutStr msg4
    nwln
    mov AX, [num1]      
    sub BH, BH  

    hex_loop:
    push AX
    mov BH, byte 16
    div BH
    mov [remainder], AH
    PutInt [remainder]
    mov [quotient], AL
    mov AX, [quotient]
    cmp [quotient], byte 0
    jz done
    loop hex_loop

    done:
    .EXIT

测试 16 位数 155 的电流输出: 二进制:11011001 八进制:332 十六进制:119

【问题讨论】:

    标签: assembly nasm


    【解决方案1】:

    您的代码有 3 个主要问题:

    • 它以相反的顺序显示数字
    • 它将十六进制数字显示为整数(例如,0xB 显示为 11)
    • 评论非常糟糕(汇编不是高级语言)

    您的代码还有其他问题:

    • 没有有效地使用寄存器(将内容存储在较慢的变量中)
    • 代码重复 - 接受“base”作为输入的单个例程将使代码大小减半
    • 滥用宏(“语言中的语言”);这使得代码更难理解(例如,我无法判断 PutInt 是函数调用还是内联代码,或者它使用/丢弃了哪些寄存器)并且无法正确优化围绕它的指令

    对于第一个问题,最好的方法是在内存中以相反的顺序构建一个字符串,然后打印结果字符串。对于第二个问题,您需要停止使用PutInt - 每个数字都应该转换为一个字符。

    例如(32 位 80x86,NASM,未经测试):

    ;Convert unsigned integer to string
    ;
    ;Input
    ; eax = integer
    ; ebx = base
    ;
    ;Output
    ; edi = address of string
    ;
    ;Trashed
    ; eax,edx
    
        section .bss
    tempString: resb 33              ;Worst case string size is 32 digits
                                     ; (for base2), plus string terminator
    tempStringEnd:
        section .text
    
    convertIntegerToString:
        mov byte [tempStringEnd-1],0 ;Store string terminator
        mov edi,tempStringEnd-2      ;edi = address to store last character
    
    .nextDigit:
        xor edx,edx                  ;edx:eax = current value
        div ebx                      ;eax = new current value, edx = next digit
        add dl,'0'                   ;dl = character for next digit maybe
        cmp dl,'9'                   ;Is the character correct?
        jbe .gotChar                 ; yes
        add dl,'A'-'0'-10            ; no, fix it up
    .gotChar:
        mov [edi],dl                 ;Store the character
        dec edi                      ;edi = address for next character
        test eax,eax                 ;Is the current value zero?
        jne .nextDigit               ; no, do the next digit
    
        ret                          ;Done, EDI = address of completed string
    

    【讨论】:

    • 感谢您的解决方案,我会将其实施到我的语言中,如果我有任何问题,请告诉您。在学习了一些高级语言(如 Python、Java 和 C++)之后,我才开始使用 Assembly,这就是为什么我仍然有高级编程倾向。
    猜你喜欢
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多