汇编语言计算器-Linux x86&;NASM-分部
我正在用汇编语言制作一个计算器,在x86处理器上执行 基本上,我的计算器要求用户输入两个数字,然后指示要对它们执行的操作(加法、减法、乘法和除法) 我的计算器可以正确地进行加法、减法和乘法,但是无法除法。在除法时,我总是得到1作为结果 然后我留下完整的申请代码:汇编语言计算器-Linux x86&;NASM-分部,linux,assembly,x86,nasm,division,Linux,Assembly,X86,Nasm,Division,我正在用汇编语言制作一个计算器,在x86处理器上执行 基本上,我的计算器要求用户输入两个数字,然后指示要对它们执行的操作(加法、减法、乘法和除法) 我的计算器可以正确地进行加法、减法和乘法,但是无法除法。在除法时,我总是得到1作为结果 然后我留下完整的申请代码: section .data ; Messages msg1 db 10,'-Calculator-',10,0 lmsg1 equ $ - msg1 ms
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
您正在将两个字节(字符)读入num1
和num2
进行数字输入。这通常是您正在键入的一位数字(0-9)和换行符。当你去做一个操作时,你把两个字节分别读入ax和bx,所以如果num1
是5,num2
是1,ax将是0xa35,bx将是0xa31。然后从每个值中减去0x30并进行除法,在所有情况下均为1,然后将其转换为0x31'1'
并打印
现在在其他情况下(add/sub),实际上是将4个字节加载到eax和ebx中。因此,当您添加
5
和1
时,您将在eax中得到0xa310a35,在ebx中得到0x???0a31(该???来自结果中发生的任何内容),但是,在从每个结果中减去0x30并添加后,eax的最低字节将为0x06,因此,当您忽略上面的字节时,您将打印6
。即使您使用汇编语言进行编码,您也应该使用C库进行系统调用,并且您的程序入口点应该是main
,而不是\u start
。非常感谢您的响应,但我无法完全理解您的答案。你能用代码的形式写下你的答案吗?很抱歉给您带来不便。我也尝试过这样做,但我得到了“浮动逗号异常”:'mov ax,[num1]mov bl,[num2];从ascii码转换为十进制子ax,'0'子bl,'0';分部。AL=DX:AX/BX分区bl;从十进制到ascii的转换加上“0”;我们移动结果mov[result],al`@NicolasObesio:如果您只接受单个数字作为输入,那么您应该只读取单个字节。使用mov al,[num]
和mov[result],al
等,并且只对单个字节执行所有相关操作。@chrisdd:我想你已经搞定了。克里斯做得很好,我不知道你知道asm!