2012-02-24 3 views
1

x86 프로세서에서 실행될 어셈블리 언어로 계산기를 만들고 있습니다.어셈블리 언어의 계산기 - Linux x86 및 NASM - Division

기본적으로 계산기는 사용자에게 두 개의 숫자를 입력 한 다음 어떤 작업 (더하기, 빼기, 곱하기 및 나눗셈)을 수행 할지를 묻습니다. , 뺄셈을 추가하고 제대로를 곱하지만를 분할 할 수없는 입니다

내 계산기. 분열을 만들 때 나는 항상 결과로 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
num1에 당신은 두 바이트 (문자)를 읽고

num2 : 여기 내 마지막 코드입니다. 이것은 일반적으로 입력하는 한 자릿수 (0-9)와 개행 문자입니다. 작업을 수행 할 때 ax와 bx로 각각 2 바이트를 읽으므로 num1이 5이고 num2이 1이면 ax는 0xa35이고 bx는 0xa31이됩니다. 그런 다음 각각에서 0x30을 빼고 모든 경우에 1을 나눈 다음 0x31 '1'으로 변환하고 인쇄하십시오.

다른 경우 (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 al, '0' \t; 결과를 이동합니다. \t mov [결과], al' –

+0

@ NicolasObesio : 한 자리 숫자 만 입력하면 1 바이트 만 읽어야합니다. 'mov al, [num]'과'mov [result], al' 등을 사용하고 모든 관련 연산을 단일 바이트에서만 수행하십시오. – hirschhornsalz