【问题标题】:Modifying bytes in assembly language 80x86?修改汇编语言 80x86 中的字节?
【发布时间】:2015-05-04 21:57:47
【问题描述】:

我目前遇到一个问题。我正在尝试输入一个数字来表示我想要总计的硬币数量,并在不使用“div”指令的情况下分别显示美元总数和美分总数。这基本上是我的整个程序:

; Assembler directives
.586                ;accept instructions for 586
.MODEL FLAT         ;generate code for flat memory
INCLUDE io.h        ;header file for input/output
.STACK 4096         ;reserve 4096-byte stack

.DATA               ; Data section begins here: reserve storage for data
numPromptP          BYTE        "How many pennies do you have?", 0  ;Prompt string for pennies
numPromptN          BYTE        "How many nickles do you have?", 0  ;Prompt string for nickles
numPromptD          BYTE        "How many dimes do you have?", 0    ;Prompt string for dimes
numPromptQ          BYTE        "How many quarters do you have?", 0 ;Prompt string for quarters
asciiInNum          BYTE        3 DUP (?)                           ;ASCII input for an integer
outCoinLabel        BYTE        "Coin Information", 0               ;string to display total amount of coins
asciiOutCoinString  BYTE        "Number of coins: ", 10 DUP (?), 0dh, 0ah, "Dollars: ", 10 DUP (?), 0dh, 0ah, "Cents: ", 10 DUP (?), 0
intP                DWORD       ?                                   ;pennies 32-bit integer
intN                DWORD       ?                                   ;nickles 32-bit integer
intD                DWORD       ?                                   ;dimes 32-bit integer
intQ                DWORD       ?                                   ;quarters 32-bit integer
coinTotal           DWORD       ?                                   ;Coin Total 32-bit integer
multiplier          DWORD       ?                                   ;32-bit integer to store value for multiplication
dollarTotal         DWORD       ?                                   ;32-bit integer to store dollar value of coins
centTotal           DWORD       ?                                   ;32-bit integer to store cent value of coins

.CODE               ; Code section begins here
_MainProc           PROC                                            ;main procedure starts here


                    ;read ASCII input for pennies, convert to 2's comp, add to coin total, and store in memory
                    input       numPromptP, asciiInNum, 3           ;prompt for, read, and store ASCII characters
                    atod        asciiInNum                          ;convert ASCII to 2's comp and store in EAX
                    mov         coinTotal, eax                      ;move amount of pennies to coinTotal
                    mov         intP, eax                           ;store pennies value in memory


                    ;read ASCII input for nickles, convert to 2's comp, add to coin total, multiply by 5, and store in memory
                    input       numPromptN, asciiInNum, 3           ;prompt for, read, and store ASCII characters
                    atod        asciiInNum                          ;convert ASCII to 2's comp and store in EAX
                    add         coinTotal, eax                      ;add amount of nickles to coinTotal
                    mov         multiplier, 5
                    mul         multiplier                          ;multiply value in EAX by 5
                    mov         intN, eax                           ;store nickles value in memory


                    ;read ASCII input for dimes, convert to 2's comp, add to coin total, multiply by 10, and store in memory
                    input       numPromptD, asciiInNum, 3           ;prompt for, read, and store ASCII characters
                    atod        asciiInNum                          ;convert ASCII to 2's comp and store in EAX
                    add         coinTotal, eax                      ;add amount of dimes to coinTotal
                    mov         multiplier, 10
                    mul         multiplier                          ;multiply value in EAX by 10
                    mov         intD, eax                           ;store 2's comp in memory

                    ;read ASCII input for quarters, convert to 2's comp, add to coin total, multiply by 25, and store in memory
                    input       numPromptQ, asciiInNum, 3           ;prompt for, read, and store ASCII characters
                    atod        asciiInNum                          ;convert ASCII to 2's comp and store in EAX
                    add         coinTotal, eax                      ;add amount of dimes to coinTotal
                    mov         multiplier, 25
                    mul         multiplier                          ;multiply value in EAX by 25
                    mov         intQ, eax                           ;store 2's comp in memory

                    ;Add up total dollar amount from coins, and store in memory
                    mov         eax, intP
                    add         eax, intN
                    add         eax, intD
                    add         eax, intQ
                    mov         dollarTotal, eax
                    mov         centTotal, eax

                    dtoa        asciiOutCoinString+16, coinTotal
                    dtoa        asciiOutCoinString+37, dollarTotal
                    dtoa        asciiOutCoinString+56, centTotal
                    output      outCoinLabel, asciiOutCoinString

                    mov         eax, 0                              ;exit with return code 0
                    ret
_MainProc           ENDP                                            ;end of main procedure
                    END                                             ;end of source code 

我的问题是......有没有办法获取存储在 eax 寄存器中的字节,这样我就可以说“在 Eax + 5 个内存位置获取字节并存储在”dollarTotal”和“获取字节存储在 EAX +6 和 EAX +7 内存位置并存储在“centTotal”中。我已经阅读了有关间接寄存器模式的信息,但我对它不太熟悉,所以我只需要指出正确的方向。我脑子里有解决方案,我只是不知道如何实现它!我当前的程序打印(如果我表示 4 个便士、4 个硬币、4 个镍币和 4 个四分之一):

Number of coins: 16
Dollars: 164 (I want this to say "1")
Coins: 164 (I want this to say "64")

【问题讨论】:

    标签: assembly byte output cpu-registers


    【解决方案1】:

    这是一种将美元和美分分开的解决方案,首先将美元总计转换为临时字符串,然后选择性地复制构成美元和美分的字符。

    dtoa tempstring, dollarTotal
    mov  al,[tempstring]
    mov  [asciiOutCoinString+37], al   ;"1"
    mov  ax,[tempstring+1]
    mov  [asciiOutCoinString+56], ax   ;"64"
    

    【讨论】:

      【解决方案2】:

      我想出了一个独特的解决方案!基本上,通过取 1/100 * 2^32,将此十进制转换为十六进制,并将此十六进制存储在内存中的乘法器中。我可以这样做:

      imul multiplier
      

      将 eax 中的美元金额乘以 1/100*2^32,它本质上将是“除以乘法”,并将 100 的位置存储在 edx 中,其余的存储在 eax 中。例如,如果我在乘法之前将“164”存储在 eax 中,并执行此指令。它将导致 1 存储在 edx 中,其余的存储在 eax 中。

      【讨论】:

      • 你将如何从 EAX 中提取 64?您仍然需要将 EAX 除以相同的 乘数
      • 我使用了同样的解决方案,得到“美元”并将其乘以 100,然后在重新加总美元和美分后从我的总数中减去它以获得美分
      猜你喜欢
      • 2014-06-06
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      相关资源
      最近更新 更多