CALCULATOR 32位
有人可以帮助我使用MASM32中的32位计算器。我认为加法和减法是可以的,但我不能用十进制打印数字;
0002FFFF - 10005 = 1fffa
在记忆中:0001 0FFFA
打印:165530十进制
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
答案 0 :(得分:1)
首先将低16位打印为十进制FFFA - > 65530和第二个字的1。
1 65530.
如果您有32位处理器,则可以使用EAX / EDX寄存器执行除法。
如果不是,那就更复杂了。然后你必须模拟一个32位的分裂。这没什么好玩的;-)。
这里有一个提示:take and skip(是的,你必须处理位)
如果你编写一个将long值除以10L的C程序,为你的处理器编译它(16位)然后对输出进行分解,你可以看到它们是如何做的。这只是一个想法。我自己没试过。您必须确保您的长值足够大,以便编译器没有机会进行优化。 ; - )
答案 1 :(得分:1)
使用EMU8086创建的下一个代码在两个单独的单词中获取32位数字,然后两者都转换为字符串。代码使用最大的32位数0FFFF FFFFh,您可以将其更改为任何其他数字,从0到FFFF FFFFh,它将起作用(注释将帮助您了解代码中发生的事情):
.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