问题
CALCULATOR 32 Bit
Can someone help me with my 32 bit calculator in MASM32. i think the adding and subtracting is OK but i cant print the number in decimal;
0002FFFF - 10005 = 1fffa
In MEMORY :0001 0FFFA
PRINTING: 165530 in decimal
DATA_HERE SEGMENT
mult1 dw 0002H
dw 0FFFFH
mult2 dw 0001H
dw 0005H
ans dw 0,0
DATA_HERE ENDS
STACK_HERE SEGMENT STACK
DW 40 DUP(0)
STACK_HERE ENDS
CODE_HERE SEGMENT
ASSUME CS:CODE_HERE, DS:DATA_HERE, SS: STACK_HERE
INICIO:
MOV AX,DATA_HERE
MOV DS,AX
ADD:
MOV AX,mult1+2 ; take lower 16-bit of NUM1; take
ADD AX,mult2+2 ; AX = AX + lower 16-bit of NUM2
MOV ans+2,AX ; Store lower 16-bit result at ans
MOV AX,mult1 ; take higher 16-bit of NUM1 in AX;
ADC AX,mult2 ; AX = AX + NUM2 + CF (add with carry)
MOV ans,AX ; Store higher 16-bit result at ans
SUBTRACT:
MOV AX,mult1+2 ; take lower 16-bit of NUM1 in AX ;
SUB AX,mult2+2 ; AX = AX - lower 16-bit of NUM2
MOV ans+2,AX ; Store lower 16-bit result at ans
MOV AX,mult1 ; take higher 16-bit of NUM1 in AX;
SUB AX,mult2 ; AX = AX - NUM2
MOV ans,AX ; Store higher 16-bit result at ans
xor si,si
mov si,0
ciclo:
mov AX, ans[si];
call display ; print AX
add si, 2
cmp si, 2
JLE ciclo
mov ax,4C00h
int 21h
display proc
;push CX
;Beginning of procedure
MOV BX, 10 ;Initializes divisor
;MOV DX, 0000H ;Clears DX
MOV CX, 0000H ;Clears CX
;Splitting process starts here
.Dloop1:
MOV DX, 0000H ;Clears DX during jump
DIV BX ;Divides AX by BX
PUSH DX ;Pushes DX(remainder) to stack
INC CX ;Increments counter to track the number of digits
CMP AX, 0 ;Checks if there is still something in AX to divide
JNE .Dloop1 ;Jumps if AX is not zero
.Dloop2: POP DX ;Pops from stack to DX
ADD DX, 30H ;Converts to it's ASCII equivalent
MOV AH, 02H
INT 21H ;calls DOS to display character
LOOP .Dloop2 ;Loops till CX equals zero
;pop CX
RET ;returns control
display ENDP
CODE_HERE ENDS
END INICIO
回答1:
You first print the lower 16 Bit as a decimal FFFA -> 65530 and the 1 from the second word.
1 65530.
If you have a 32 Bit Processor you can perform you division with EAX/EDX registers.
If not it is more complicated. Then you have to simulate a 32 Bit divission. That's no fun ;-).
Here's a hint: http://en.wikipedia.org/wiki/Division_algorithm (yes you must handle bits)
If you write a C programm that divides a long value by 10L, compile it for your processor (16 Bit) and dissasemble the output then, you can see how they do it. It's just an idea. I have not tried it myself. You must asure that your long value is big enough so that the compiler has no chance to optimize. ;-)
回答2:
Next code, made with EMU8086 gets a 32 bit number in two separated words, then both are converted into string. The code uses the biggest 32 bit number 0FFFF FFFFh, you can change it for any other number, from 0 to FFFF FFFFh, it will work (comments will help you understand what is going on in the code) :
.model small
.stack 100h
.data
num_low dw ? ;32 BIT
num_hig dw ? ;NUMBER.
buf db 12 dup('$') ;NUMBER CONVERTED TO STRING.
.code
start:
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;STORE BIG 32 BIT NUMBER = 4294967295 = 0FFFF FFFFh.
mov num_low, 0FFFFh
mov num_hig, 0FFFFh
;CONVERT 32 BIT NUMBER TO STRING.
mov si, offset buf
call number2string32bit
;DISPLAY STRING (32 BIT NUMBER CONVERTED).
mov ah, 9
mov dx, offset buf
int 21h
;WAIT FOR ANY KEY.
mov ah, 7
int 21h
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;------------------------------------------
;CONVERT 32 BIT NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE DIVIDING
;NUMBER BY 10, STORING REMAINDERS IN STACK, THEN
;EXTRACT THEM IN REVERSE ORDER TO BUILD STRING.
;PARAMETERS : num_low = LOW WORD OF 32 BIT NUMBER.
; num_hig = HIGH WORD OF 32 BIT NUMBER.
; SI = POINTING WHERE TO STORE STRING.
number2string32bit proc
mov bx, 10 ;DIVIDE NUMBER BY 10 TO EXTRACT DIGITS.
mov cx, 0 ;DIGITS COUNTER. NECESSARY TO POP REMAINDERS.
extracting:
;DIVIDE HIGHER WORD OF 32 BIT NUMBER.
mov dx, 0 ;DX NOT NECESSARY FOR THE HIGH WORD.
mov ax, num_hig
div bx
mov num_hig, ax ;HIGHER WORD OF RESULT.
;DIVIDE LOWER WORD OF 32 BIT NUMBER.
;VERY IMPORTANT : PREVIOUS DX IS NECESSARY FOR THE LOW WORD.
mov ax, num_low
div bx
mov num_low, ax ;LOWER WORD OF RESULT.
push dx ;STORE REMAINDER (EXTRACTED DIGIT).
inc cx ;INCREASE DIGIT COUNTER.
;CHECK END OF PROCESS.
cmp ax, 0 ;IF LOWER WORD IS
jne extracting ;NOT ZERO, REPEAT.
;NOW RETRIEVE PUSHED DIGITS. THERE ARE CX DIGITS STORED IN STACK.
poping:
pop dx ;GET STORED DIGIT.
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl ;STORE CHARACTER IN STRING.
inc si ;POSITION FOR NEXT CHARACTER.
loop poping ;CX--. IF ( CX > 0 ) REPEAT.
ret
number2string32bit endp
;------------------------------------------
end start
来源:https://stackoverflow.com/questions/30375682/32-bit-calculator-in-8086-assembly