2015-05-21 2 views
-1

КАЛЬКУЛЯТОР 32 Бит32 бит Калькулятор в 8086 Сборка

Может кто-нибудь помочь мне с моим 32-битным калькулятором в MASM32. Я думаю, что добавление и вычитание в порядке, но я не могу напечатать число в десятичном формате;

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

Очевидно, что вы не можете печатать десятичные числа из двух частей отдельно. Вы можете создать 32-битное деление или использовать другой подход, такой как повторение вычитания степеней 10. – Jester

+0

Если вы можете найти копию старой книги/библиотеки Spontaneous Assembly, которая имеет встроенные макросы, которые вы можете использовать. –

+0

Прошу прощения за предыдущие попытки (вы понимаете^_º), это окончательная версия, которая работает с любым 32-битным числом, от 0 до FFFFFFFFh. –

ответ

1

Сначала распечатайте нижний 16 бит в виде десятичного FFFA -> 65530 а 1 со второго слова.

1 65530.

Если у вас есть 32-битный процессор позволяет выполнять вам разделение с регистрами EAX/EDX.

Если нет, это сложнее. Затем вы должны имитировать 32-разрядное деление. Это не забавно ;-).

Вот подсказка: http://en.wikipedia.org/wiki/Division_algorithm (да, вы должны обрабатывать биты)

Если вы пишете C программку, которая разделяет длинное значение по 10L, компилировать его для процессора (16 бит) и dissasemble выхода тогда вам могут видеть, как они это делают. Это просто идея. Я сам не пробовал. Вы должны заявить, что ваше длинное значение достаточно велико, чтобы компилятор не имел возможности оптимизировать. ;-)

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 
+0

спасибо за код, я тестировал номер2string32bit proc, но я думаю, что он не печатает правильно. 1FFFA = 131066 и печатает 165530 –

+0

Исправлена ​​неправильная печать. –