2012-02-24 28 views
1

私はx86プロセッサ上で実行されるアセンブリ言語の電卓を作っています。アセンブリ言語の電卓 - Linux x86&NASM - Division

基本的に、私の電卓は、2つの数字を入力して、どの操作(加算、減算、乗算、除算)をしたいのかをユーザーに尋ねます。 、減算を追加し、正しくを乗算したがを分割することができませんでしある

私の電卓。部門を作る際には、常に結果として1を得る。

その後、私は自分のアプリケーションのコードの完全なを残す:

section .data 

    ; Messages 

    msg1  db  10,'-Calculator-',10,0 
    lmsg1  equ  $ - msg1 

    msg2  db  10,'Number 1: ',0 
    lmsg2  equ  $ - msg2 

    msg3  db  'Number 2: ',0 
    lmsg3  equ  $ - msg3 

    msg4  db  10,'1. Add',10,0 
    lmsg4  equ  $ - msg4 

    msg5  db  '2. Subtract',10,0 
    lmsg5  equ  $ - msg5 

    msg6  db  '3. Multiply',10,0 
    lmsg6  equ  $ - msg6 

    msg7  db  '4. Divide',10,0 
    lmsg7  equ  $ - msg7 

    msg8  db  'Operation: ',0 
    lmsg8  equ  $ - msg8 

    msg9  db  10,'Result: ',0 
    lmsg9  equ  $ - msg9 

    msg10  db  10,'Invalid Option',10,0 
    lmsg10  equ  $ - msg10 

    nlinea  db  10,10,0 
    lnlinea  equ  $ - nlinea 

section .bss 

    ; Spaces reserved for storing the values ​​provided by the user. 

    opc   resb 2 
    num1  resb 2 
    num2  resb 2 
    result  resb 2 

section .text 

    global _start 

_start: 

    ; Print on screen the message 1 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg1 
    mov edx, lmsg1 
    int 80h 

    ; Print on screen the message 2 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg2 
    mov edx, lmsg2 
    int 80h 

    ; We get num1 value. 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, num1 
    mov edx, 2 
    int 80h 

    ; Print on screen the message 3 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg3 
    mov edx, lmsg3 
    int 80h 

    ; We get num2 value. 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, num2 
    mov edx, 2 
    int 80h 

    ; Print on screen the message 4 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg4 
    mov edx, lmsg4 
    int 80h 

    ; Print on screen the message 5 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg5 
    mov edx, lmsg5 
    int 80h 

    ; Print on screen the message 6 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg6 
    mov edx, lmsg6 
    int 80h 

    ; Print on screen the message 7 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg7 
    mov edx, lmsg7 
    int 80h 

    ; Print on screen the message 8 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg8 
    mov edx, lmsg8 
    int 80h 

    ; We get the option selected. 
    mov ebx,0 
    mov ecx,opc 
    mov edx,2 
    mov eax,3 
    int 80h 

    mov ah, [opc] ; Move the selected option to the registry ah 
    sub ah, '0'  ; Convert from ascii to decimal 

    ; We compare the value entered by the user to know what operation to perform. 

    cmp ah, 1 
    je add 
    cmp ah, 2 
    je subtract 
    cmp ah, 3 
    je multiply 
    cmp ah, 4 
    je divide 

    ; If the value entered by the user does not meet any of the above 
    ; conditions then we show an error message and we close the program. 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg10 
    mov edx, lmsg10 
    int 80h 

    jmp exit 

add: 
    ; We keep the numbers in the registers eax and ebx 
    mov eax, [num1] 
    mov ebx, [num2] 

    ; Convert from ascii to decimal 
    sub eax, '0' 
    sub ebx, '0' 

    ; Add 
    add eax, ebx 

    ; Conversion from decimal to ascii 
    add eax, '0' 

    ; We move the result 
    mov [result], eax 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 1 
    int 80h 

    ; We end the program 
    jmp exit 

subtract: 
    ; We keep the numbers in the registers eax and ebx 
    mov eax, [num1] 
    mov ebx, [num2] 

    ; Convert from ascii to decimal 
    sub eax, '0' 
    sub ebx, '0' 

    ; Subtract 
    sub eax, ebx 

    ; Conversion from decimal to ascii 
    add eax, '0' 

    ; We move the result 
    mov [result], eax 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 1 
    int 80h 

    ; We end the program 
    jmp exit 

multiply: 

    ; We store the numbers in registers ax and bx 
    mov ax, [num1] 
    mov bx, [num2] 

    ; Convert from ascii to decimal 
    sub ax, '0' 
    sub bx, '0' 

    ; Multiply. AL = AX x BX 
    mul bx 

    ; Conversion from decimal to ascii 
    add al, '0' 

    ; We move the result 
    mov [result], al 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 1 
    int 80h 

    ; We end the program 
    jmp exit 

divide: 
    ; IN THIS LABEL IS THE ERROR! 

    ; We store the numbers in registers ax and bx 
    mov dx, 0 
    mov ax, [num1] 
    mov bx, [num2] 

    ; Convert from ascii to decimall 
    sub ax, '0' 
    sub bx, '0' 
    ; Division. AX = DX:AX/BX 
    div bx 

    ; Conversion from decimal to ascii 
    add ax, '0' 
    ; We move the result 
    mov [result], ax 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    ; ALWAYS PRINTS 1 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 1 
    int 80h 

    ; We end the program 
    jmp exit 

exit: 
    ; Print on screen two new lines 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, nlinea 
    mov edx, lnlinea 
    int 80h 
    ; End the program 
    mov eax, 1 
    mov ebx, 0 
    int 80h 

エラーがタグ「分割」の中に発見されなければなりません。

分割の結果として常に1を得るのはなぜですか?

これ以上の経験を持つ人が私を助けてくれることを願っています。


ありがとうございました。私の電卓がついに動作します。ここに私の最終的なコードは次のとおりです。

section .data 

    ; Messages 

    msg1  db  10,'-Calculator-',10,0 
    lmsg1  equ  $ - msg1 

    msg2  db  10,'Number 1: ',0 
    lmsg2  equ  $ - msg2 

    msg3  db  'Number 2: ',0 
    lmsg3  equ  $ - msg3 

    msg4  db  10,'1. Add',10,0 
    lmsg4  equ  $ - msg4 

    msg5  db  '2. Subtract',10,0 
    lmsg5  equ  $ - msg5 

    msg6  db  '3. Multiply',10,0 
    lmsg6  equ  $ - msg6 

    msg7  db  '4. Divide',10,0 
    lmsg7  equ  $ - msg7 

    msg8  db  'Operation: ',0 
    lmsg8  equ  $ - msg8 

    msg9  db  10,'Result: ',0 
    lmsg9  equ  $ - msg9 

    msg10  db  10,'Invalid Option',10,0 
    lmsg10  equ  $ - msg10 

    nlinea  db  10,10,0 
    lnlinea  equ  $ - nlinea 

section .bss 

    ; Spaces reserved for storing the values ​​provided by the user. 

    opc:  resb 2 
    num1:  resb 2 
    num2:  resb 2 
    result:  resb 2 

section .text 

    global _start 

_start: 

    ; Print on screen the message 1 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg1 
    mov edx, lmsg1 
    int 80h 

    ; Print on screen the message 2 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg2 
    mov edx, lmsg2 
    int 80h 

    ; We get num1 value. 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, num1 
    mov edx, 2 
    int 80h 

    ; Print on screen the message 3 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg3 
    mov edx, lmsg3 
    int 80h 

    ; We get num2 value. 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, num2 
    mov edx, 2 
    int 80h 

    ; Print on screen the message 4 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg4 
    mov edx, lmsg4 
    int 80h 

    ; Print on screen the message 5 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg5 
    mov edx, lmsg5 
    int 80h 

    ; Print on screen the message 6 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg6 
    mov edx, lmsg6 
    int 80h 

    ; Print on screen the message 7 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg7 
    mov edx, lmsg7 
    int 80h 

    ; Print on screen the message 8 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg8 
    mov edx, lmsg8 
    int 80h 

    ; We get the option selected. 
    mov ebx,0 
    mov ecx,opc 
    mov edx,2 
    mov eax,3 
    int 80h 

    mov ah, [opc]  ; Move the selected option to the registry ah 
    sub ah, '0'  ; Convert from ascii to decimal 

    ; We compare the value entered by the user to know what operation to perform. 

    cmp ah, 1 
    je add 
    cmp ah, 2 
    je subtract 
    cmp ah, 3 
    je multiply 
    cmp ah, 4 
    je divide 

    ; If the value entered by the user does not meet any of the above 
    ; conditions then we show an error message and we close the program. 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg10 
    mov edx, lmsg10 
    int 80h 

    jmp exit 

add: 
    ; We keep the numbers in the registers al and bl 
    mov al, [num1] 
    mov bl, [num2] 

    ; Convert from ascii to decimal 
    sub al, '0' 
    sub bl, '0' 

    ; Add 
    add al, bl 

    ; Conversion from decimal to ascii 
    add al, '0' 

    ; We move the result 
    mov [result], al 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 2 
    int 80h 

    ; We end the program 
    jmp exit 

subtract: 
    ; We keep the numbers in the registers al and bl 
    mov al, [num1] 
    mov bl, [num2] 

    ; Convert from ascii to decimal 
    sub al, '0' 
    sub bl, '0' 

    ; Subtract 
    sub al, bl 

    ; Conversion from decimal to ascii 
    add al, '0' 

    ; We move the result 
    mov [result], al 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 1 
    int 80h 

    ; We end the program 
    jmp exit 

multiply: 

    ; We store the numbers in registers al and bl 
    mov al, [num1] 
    mov bl, [num2] 

    ; Convert from ascii to decimal 
    sub al, '0' 
    sub bl, '0' 

    ; Multiply. AX = AL x BL 
    mul bl 

    ; Conversion from decimal to ascii 
    add ax, '0' 

    ; We move the result 
    mov [result], ax 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 1 
    int 80h 

    ; We end the program 
    jmp exit 

divide: 

    ; We store the numbers in registers ax and bx 
    mov al, [num1] 
    mov bl, [num2] 

    mov dx, 0 
    mov ah, 0 

    ; Convert from ascii to decimall 
    sub al, '0' 
    sub bl, '0' 

    ; Division. AL = AX/BX 
    div bl 

    ; Conversion from decimal to ascii 
    add ax, '0' 
    ; We move the result 
    mov [result], ax 

    ; Print on screen the message 9 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, msg9 
    mov edx, lmsg9 
    int 80h 

    ; Print on screen the result 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, result 
    mov edx, 1 
    int 80h 

    ; We end the program 
    jmp exit 

exit: 
    ; Print on screen two new lines 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, nlinea 
    mov edx, lnlinea 
    int 80h 
    ; End the program 
    mov eax, 1 
    mov ebx, 0 
    int 80h 
+1

アセンブリ言語でコーディングしていても、Cライブラリを使ってシステムコールを行う必要があります。プログラムエントリポイントは '_start'ではなく' main'にしてください。 – zwol

答えて

2

あなたはあなたの番号の入力をnum1num2に2バイト(文字)を読んでいます。これは通常、入力する1桁の数字(0-9)と改行文字になります。操作を行うと、axとbxにそれぞれ2バイトが読み込まれるので、num1が5でnum2が1だった場合、axは0xa35になり、bxは0xa31になります。その後、それぞれから0x30を引いて割り、すべての場合に1を与え、次に0x31に変換してに変換して印刷します。

他の場合(add/sub)、実際には4バイトをeaxとebxにロードしています。したがって、51を追加すると、eaxには0xa310a35、ebxには0x ???? 0a31が返されます(この数字はresultに存在するものに由来します)。ただし、0x30をそれぞれ減算して加算した後、 eaxの最下位バイトは0x06なので、上のバイトにあるものを無視するので、6を印刷します。

+0

ありがとう、私はあなたの答えを完全に理解することはできません。答えをコードの形で書いてください。ご不便おかけしてすみません。 –

+0

また、私はこれをやってみたが、私は "フローティングコンマ例外" を得る: '\tのmov斧、[NUM1] \tのMOV BL、[NUM2] \t。 asciiからdecimallへの変換 \t sub ax、 '0' \t sub bl、 '0' \t;分割。AL = DX:AX/BX \t div bl \t;小数からasciiへの変換 \t add al、 '0' \t;結果を移動します \t mov [result]、al' –

+0

@NicolasObesio:入力として1桁のみを受け入れる場合は、1バイトだけを読み込む必要があります。 'mov al、[num]'と 'mov [result]、al'などを使用し、すべての関連する操作を1バイトだけで行います。 – hirschhornsalz

関連する問題