gpt4 book ai didi

linux - 汇编语言计算器 - Linux x86 和 NASM - 分部

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:27:26 26 4
gpt4 key购买 nike

我正在用汇编语言制作一个在 x86 处理器上执行的计算器。

基本上,我的计算器要求用户输入两个数字,然后指示要对它们执行的运算(加法、减法、乘法和除法)。

我的计算器可以正确地加、减和乘,但无法除法。在做除法时,结果总是 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

错误必须在标记“divide”内找到。

为什么除法的结果总是 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

最佳答案

您正在将两个字节(字符)读入 num1num2 以供您输入数字。这通常是您输入的单个数字 (0-9) 和一个换行符。当你去做一个操作时,你将 2 个字节分别读入 ax 和 bx,所以如果 num1 是 5 并且 num2 是 1,ax 将是 0xa35 并且 bx 将是0xa31。然后从每个减去 0x30 并相除,在所有情况下都得到 1,然后将其转换为 0x31 '1' 并打印。

现在在其他情况下(添加/子),您实际上是将 4 个字节加载到 eax 和 ebx 中。因此,当您添加 51 时,您将在 eax 中得到 0xa310a35,在 ebx 中得到 0x????0a31(???? 来自恰好是在 result 中。)但是,在从每个减去 0x30 并相加之后,eax 的最低字节将为 0x06,因此您将打印 6,因为您忽略了上面的内容字节。

关于linux - 汇编语言计算器 - Linux x86 和 NASM - 分部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9435659/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com