【问题标题】:Calculator in NASMNASM 中的计算器
【发布时间】:2012-12-28 18:56:09
【问题描述】:

我正在尝试在 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

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

【问题讨论】:

  • 您在上传之前可能无意中从代码中删除了所有 cmets ?
  • 使用调试器单步调试代码。
  • @Inver:只是好奇一下,你真的是在 MS-DOS 操作系统中运行它还是只是在虚拟机/DOS 模拟器上运行它?
  • 我在用 DosBox,玩老游戏也是一样的 ;)。

标签: assembly x86 nasm dos dosbox


【解决方案1】:

这可能不是一个“答案”......无论如何都不是“那个”答案......但对我来说它看起来“错误”。

; WYBOR DZIALANIA
mov ah, 0
int 16h

cmp al, '1' 
je dodawanie 

cmp al, '5'
je wyjscie


dodawanie:

如果输入正好是“5”,我们转到wyjscie(波兰语表示“退出”?)。任何其他输入 - 包括但不限于“1” - 我们“落入”dodawanie。这是你想要的吗?

【讨论】:

  • 哈哈是的。 2,3,4 用于其余操作。目前我只专注于添加数字,如果这可行,我会休息。
  • 好的。关注 nrz 已确定的问题。很好,nrz!
  • dodawanie 表示加法
【解决方案2】:

因为绝对没有 cmets,所以很难理解发生了什么。

liczbe_na_tekst函数中,一开始你推送cxdxsi,但最后你弹出axdxcx。在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 重写为ax(丢失了您之前存储在bl 中的一条指令的'$')。 bx 现在包含bufor + 2 的地址(最初来自lea si, [bufor + 2]),然后'$' 代替bl 现在包含bufor + 2 地址的低8 位。

mov [bx+liczba], bl

那么,这里你写到[bufor+liczba+2]bufor + 2地址的低8位,而不是'$'bx 这里包含bufor + 2 的地址。

我认为这不是你打算做的。当您修改liczbe_na_teksttekst_na_liczbe 的代码时,您的代码可能会崩溃(当您将地址buforliczba 相加,而子函数liczbe_na_teksttekst_na_liczbe 在内存中的数据之后)` ,当 CPU 遇到非法指令或进入无限循环时程序崩溃。

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

liczbe_na_tekstpushpop指令:

liczbe_na_tekst:
    push ax
    push cx
    push dx
    push si
    ...
    pop si
    pop dx
    pop cx
    pop ax
    ret

然后call liczbe_na_tekst之后:

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

可能还需要一些其他修复。没有测试。

【讨论】:

  • 非常感谢 nrz 我会尽快测试它;D
猜你喜欢
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
  • 2013-06-26
  • 2014-08-27
  • 2015-07-08
相关资源
最近更新 更多