NASM中的计算器

时间:2013-01-14 19:01:21

标签: assembly x86 nasm dos dosbox

我正在尝试在NASM(Asembly)中编写计算器。它没有显示任何错误,但不知何故,我输入两个数字后添加它们,程序只是卡住了。之后无能为力。

这是代码:

org 100h

_start:
;LOGO
mov ah, 9
mov dx, logo1
int 21h

mov ah, 9
mov dx, logo2
int 21h


;MENU
mov ah, 9
mov dx, ramka1
int 21h

mov ah, 9
mov dx, wybor
int 21h

mov ah, 9
mov dx, dzialanie1
int 21h

mov ah, 9
mov dx, dzialanie2
int 21h

mov ah, 9
mov dx, dzialanie3
int 21h

mov ah, 9
mov dx, dzialanie4
int 21h

mov ah, 9
mov dx, dzialanie5
int 21h

mov ah, 9
mov dx, ramka2
int 21h

mov ah, 9
mov dx, nwln
int 21h


; WYBOR DZIALANIA
mov ah, 0
int 16h

cmp al, '1' 
je dodawanie 

cmp al, '5'
je wyjscie


dodawanie:

mov ah, 9
mov dx, zmienna1
int 21h

mov ah, 0ah
mov dx, bufor
int 21h

lea si, [bufor + 2] 
mov cx, 0
mov cl, [bufor + 1]
call tekst_na_liczbe

mov [liczba1], ax

mov ah, 9
mov dx, nwln
int 21h

mov ah, 9
mov dx, zmienna2
int 21h

mov ah, 0ah
mov dx, bufor
int 21h

lea si, [bufor + 2]
mov cx, 0
mov cl, [bufor + 1]
call tekst_na_liczbe

add ax, [liczba1]

mov di, liczba
call liczbe_na_tekst

mov bl, '$'
mov bx,ax
mov [bx+liczba], bl

mov ah, 9
mov dx, wynik
int 21h

mov ah, 9
mov dx, liczba
int 21h

mov ah, 9
mov dx, nwln
int 21h

mov ah, 9
mov dx, nwln
int 21h

jmp _start


;WYJSCIE
wyjscie:

mov ax, 4C00h
int 21h

zmienna1 db "||Podaj pierwsza liczbe: $"

bufor db 15
db 0
times 15 db '$'

liczba db 15
db 0
times 15 db '$'

zmienna2 db "||Podaj druga liczbe: $"

liczba1 dd 0
liczba2 dd 0

wynik db 10, 13, "//Wynik: $"

nwln db 10, 13, '$'

menu db "Wybierz dzialanie:", 10, 13, 10, 13, '$'

;WYSWIETLENIE LOGO I MENU
logo1 db      "==============================================", 10, 13, "$"
logo2 db      "||Kalkulator w ASM                          ||", 10, 13, "$"
ramka1 db     "==============================================", 10, 13, "$"
wybor db      "||Wybierz dzialanie:                        ||", 10, 13, "$"
dzialanie1 db "||1.Dodawanie                               ||", 10, 13, "$"
dzialanie2 db "||2.Odejmowanie                             ||", 10, 13, "$"
dzialanie3 db "||3.Mnozenie                                ||", 10, 13, "$"
dzialanie4 db "||4.Dzielenie                               ||", 10, 13, "$"
dzialanie5 db "||5.Wyjcie z kalkulatora                    ||", 10, 13, "$"
ramka2 db     "==============================================", "$"



liczbe_na_tekst:
push cx
push dx
push si
mov cx, 10 
mov si, 0 
.dziel:
mov dx, 0 
div cx 
add dl, '0' 
mov bp,di
add di,si
mov dl,[bp]
inc si 
cmp ax, 1
jge .dziel 
push esi 
dec esi 
mov ecx, 0 
.odwroc:
mov bx, di 
mov di, cx 
add di, cx 
mov al,[bx] 
inc cx 
dec si
cmp cx, si
jl .odwroc 
pop ax 
pop dx
pop cx
ret


tekst_na_liczbe:
push bx
push dx
mov ax, 0 
mov bx, 0 
.petla:
mov dx, 10 
mul dx 
mov dl, [si+bx] 
sub dl, '0' 
add ax, dx 
inc bx 
cmp bx, cx 
jl .petla 
pop dx
pop bx
ret

对不起,部分代码是波兰语,但总体上应该理解。非常感谢你的帮助!

2 个答案:

答案 0 :(得分:1)

由于绝对没有评论,因此很难理解发生了什么。

liczbe_na_tekst函数中,您可以在开头推送cxdxsi,但最后您弹出ax,{{1} },dx。在cx call liczbe_na_tekst似乎包含缓冲区的地址之前。在si结束时,它会传递给liczbe_na_tekst

ax标签后:

dodawanie

在这里,您首先将dodawanie: ... lea si, [bufor + 2] ... call liczbe_na_tekst mov bl, '$' mov bx,ax 写入'$',但立即使用bl bx ower写ax'$'只丢失bl先前的一条指令)。 bx现在包含bufor + 2的地址(最初来自lea si, [bufor + 2]),然后代替'$'bl现在包含{的低8位地址{ {1}}。

bufor + 2

然后,在这里,您向mov [bx+liczba], bl 写入[bufor+liczba+2]地址的低8位,而不是bufor + 2'$'此处包含bx的地址。

我认为这不是你打算做的。当您修改bufor + 2liczbe_na_tekst的代码时(当您对地址tekst_na_liczbebufor以及子功能liczba和{{进行求和)时,您的代码可能会崩溃1}}在你的数据存储器之后``,程序在CPU达到非法指令时崩溃或者进入无限循环。

我认为您至少需要修复以下部分:

liczbe_na_tekst的{​​{1}}和tekst_na_liczbe说明:

push

然后在pop之后:

liczbe_na_tekst

也可能需要其他一些修复。尚未测试过。

答案 1 :(得分:1)

这可能不是一个“答案”......而不是“答案”......但它对我来说看起来“错误”。

; WYBOR DZIALANIA
mov ah, 0
int 16h

cmp al, '1' 
je dodawanie 

cmp al, '5'
je wyjscie


dodawanie:

; WYBOR DZIALANIA mov ah, 0 int 16h cmp al, '1' je dodawanie cmp al, '5' je wyjscie dodawanie: 如果输入完全是'5',我们转到(波兰语为“退出”?)。任何其他输入 - 包括但不限于'1' - 我们“落到”wyjscie。这是你想要的吗?