1

NASM (Asembly) で電卓を書こうとしています。エラーは表示されませんが、2 つの数字を入力してそれらを追加した後、プログラムが動かなくなりました。後はどうしようもない。

コードは次のとおりです。

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

申し訳ありませんが、コードの一部はポーランド語ですが、全体的には理解できるはずです。助けてくれてどうもありがとう!

4

2 に答える 2

1

コメントがまったくないので、何が起こっているのかわかりにくいです。

liczbe_na_tekst関数では、最初は 、 、 を押しますがcxdx最後に、、siをポップします。Beforeにはバッファへのアドレスが含まれているようです。最後にに渡されます。axdxcxcall liczbe_na_tekst siliczbe_na_tekstax

dodawanieラベルの後:

dodawanie:
 ...
lea si, [bufor + 2]
...
call liczbe_na_tekst

mov bl, '$'
mov bx,ax

ここでは、最初に書き込みます'$'bl、すぐに上書きbxします (前に 1 つの命令で保存したことをax失います)。には(元は からの)のアドレスが含まれるようになり、の代わりにのアドレスの下位 8 ビットが含まれるようになりました。'$'blbxbufor + 2lea si, [bufor + 2]'$'blbufor + 2

mov [bx+liczba], bl

次に、ここではではなく[bufor+liczba+2]のアドレスの下位 8 ビットに書き込みます。のアドレスがここに含まれます。bufor + 2'$'bxbufor + 2

これはあなたが意図していることではないと思います。liczbe_na_tekstおそらく、またはのコードを変更するとコードがクラッシュしtekst_na_liczbe(アドレスbuforliczbaサブ関数liczbe_na_tekstを合計tekst_na_liczbeし、メモリ内のデータの後にあるため)`、CPU が不正な命令に到達するか、無限ループに入るとプログラムがクラッシュします。 .

少なくとも次の部分を修正する必要があると思います。

pushとのpop説明liczbe_na_tekst:

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 '$'

他のいくつかの修正も必要になる場合があります。テストしていません。

于 2013-01-14T19:27:24.437 に答える
1

これはおそらく「答え」ではありません...とにかく「その」答えではありません...しかし、私には「間違っている」ように見えます。

; WYBOR DZIALANIA
mov ah, 0
int 16h

cmp al, '1' 
je dodawanie 

cmp al, '5'
je wyjscie


dodawanie:

入力が正確に '5' の場合、wyjscie(ポーランド語で「終了」?) に進みます。「1」を含むがこれに限定されないその他の入力は、 に「フォールスルー」しdodawanieます。これはあなたが意図したものですか?

于 2013-01-14T20:00:18.300 に答える