32 bit Calculator in 8086 Assembly

你说的曾经没有我的故事 提交于 2019-12-13 08:58:31

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!