8086汇编中的32位计算器

时间:2015-05-21 13:48:48

标签: assembly calculator x86-16 masm32

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

2 个答案:

答案 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