Chase Rutledge
Chase Rutledge

Reputation: 35

Modifying bytes in assembly language 80x86?

I am currently stuck with a problem. I am trying to input a number for the number of coins I want totaled up, and display the total number of dollars and the total number of cents separately WITHOUT using "div" instruction. This is basically my entire program:

; 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 

My question is... is there a way to get at the bytes that are stored in eax register, so that I can say "Take the Byte at Eax + 5 memory locations and store in "dollarTotal" and "take the byte's stored at EAX +6 and EAX +7 memory locations and store in "centTotal". I have read about indirect register mode, but I am not too familiar with it so I just need to be pointed in the right direction. I have the solution in my head, I just don't know how to implement it! My current program prints (If I indicated 4 pennies, 4 dimes, 4 nickles, and 4 quarters) :

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

Upvotes: 0

Views: 753

Answers (2)

Fifoernik
Fifoernik

Reputation: 9899

Here's a solution to separate dollars and cents by first converting the dollartotal in a tempstring and then selectively copying the characters that make out dollars and cents.

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

Upvotes: 0

Chase Rutledge
Chase Rutledge

Reputation: 35

I have came up with a unique solution! Basically, by taking 1/100 * 2^32, converting this decimal to hex, and storing this hex in a multiplier in memory. I can do this :

imul multiplier

Multiply the value of the dollar amount in eax by 1/100*2^32 and it will essentially be a "division by multiplication", and store the 100's position in edx and the rest in eax. So for example, if I have "164" stored in eax before multiplication, and perform this instruction. It will result in 1 being stored in edx, and the rest in eax.

Upvotes: 1

Related Questions