我刚刚尝试创建一个计算器来简单地执行 5 种不同的操作(加、减、除和对数),但在 Turbo Assembler 中汇编代码时遇到问题。 任何想法如何解决这个问题?
我尝试执行上面的代码,但出现此错误 这是代码:
.model small
.data
msg_input1 db 'Enter the first number: $'
msg_input2 db 'Enter the second number: $'
msg_operation db 'Choose operation (1: Add, 2: Multiply, 3: Subtract, 4: Divide, 5: Logarithm): $'
msg_result db 'Result: $'
msg_error db 'Error: Division by zero!$'
num1 dw ?
num2 dw ?
result dw ?
buffer db 6 dup(?) ; buffer to store result as a string
.code
main:
mov ax, @data
mov ds, ax
; Input the first number
mov ah, 9
mov dx, offset msg_input1
int 21h
call input_number
mov num1, ax
; Input the second number
mov ah, 9
mov dx, offset msg_input2
int 21h
call input_number
mov num2, ax
; Choose operation
mov ah, 9
mov dx, offset msg_operation
int 21h
mov ah, 1
int 21h
sub al, '0'
; Perform the selected operation
cmp al, '1'
je add_operation
cmp al, '2'
je multiply_operation
cmp al, '3'
je subtract_operation
cmp al, '4'
je divide_operation
cmp al, '5'
je logarithm_operation
jmp invalid_operation
add_operation:
mov ax, num1
add ax, num2
mov result, ax
jmp display_result
multiply_operation:
mov ax, num1
call multiply_num2
mov result, ax
jmp display_result
subtract_operation:
mov ax, num1
sub ax, num2
mov result, ax
jmp display_result
divide_operation:
cmp num2, 0
je division_by_zero
mov ax, num1
cwd
idiv num2
mov result, ax
jmp display_result
logarithm_operation:
; Your code for logarithm operation goes here
invalid_operation:
; Handle invalid operation
jmp end_program
multiply_num2 proc
; Multiply AX by num2
mov bx, num2
mov cx, ax
xor ax, ax
multiply_loop:
add ax, cx
loop multiply_loop
ret
multiply_num2 endp
division_by_zero:
; Display an error message
mov ah, 9
mov dx, offset msg_error
int 21h
jmp end_program
display_result proc
; Convert the result to a string
mov ax, result
mov cx, 10
mov di, offset buffer + 4
mov si, 0
convert_digit:
xor dx, dx
div cx
add dl, '0'
dec di
mov [di], dl
inc si
test ax, ax
jnz convert_digit
; Display the result message
mov ah, 9
mov dx, offset msg_result
int 21h
; Display the result string
mov ah, 9
lea dx, [di]
int 21h
; Display a new line
mov ah, 2
mov dl, 0Dh
int 21h
mov dl, 0Ah
int 21h
ret
display_result endp
input_number proc
; Initialize buffer
mov si, offset buffer
mov cx, 6
mov di, 0
rep stosb
; Read multiple characters
mov cx, 6
mov ah, 0
input_loop:
int 21h
cmp al, 13 ; Check for Enter key
je input_done
mov [si], al
inc si
loop input_loop
input_done:
; Convert buffer to number
mov si, offset buffer
mov cx, 6
xor ax, ax
convert_loop:
mov al, [si]
cmp al, '$' ; Check for end of buffer
je convert_done
sub al, '0'
imul ax, 10
add ax, dx
add ax, al
inc si
loop convert_loop
convert_done:
ret
input_number endp
end_program:
; Exit program
mov ah, 4Ch
mov al, 0
int 21h
end main
以下是错误:
汇编文件:Calc.asm 伊穆尔斧头,10 Error Calc.asm(175) 线上有多余字符 添加斧头,艾尔 错误 Calc.asm(177) 操作数类型不匹配
Assembling file: Calc.asm imul ax, 10 **Error** Calc.asm(175) Extra characters on line add ax, al **Error** Calc.asm(177) Operand types do not match
有关错误消息的说明,请参阅 Jester 的评论 和 PeterCordes 的评论。
接下来是对程序中错误的不完整总结。它至少应该允许您检查加法和减法运算。
input_number过程从缓冲区的错误初始化开始!
rep stosb
使用您错误地设置为零而不是buffer 的 DI。因此,您将覆盖 msg_input1 消息的前 6 个字节。您将用重复的“$”字符填充它,因为这是 DOS.PrintString 函数 09h 返回时留在 AL 寄存器中的内容。
当您“读取多个字符”时,您使用了错误的功能编号!
mov ah, 0
选择退出程序的功能。您需要 DOS.GetKey Strike 函数 01h。
由于我已经提到的第一个错误,“将缓冲区转换为数字”循环将徒劳地寻找“$”字符!
并且由于 AL 寄存器(8 位)是 AX 寄存器(16 位)的一部分,因此您不能将计算出的数字保留在 AX 中,同时将下一个数字加载到 AL 中。乘法使用 AX(在 8086 上),因此请为数字选择另一个寄存器。
在下面的代码中,6 字节缓冲区有可容纳 5 个十进制数字和 1 字节终止符 (13) 的空间。我确保这些数字实际上是有效的十进制数字。最多可以输入99999,所以还是有可能溢出的。
input_number proc
mov di, offset buffer
mov cx, 5
input_loop:
mov ah, 01h
int 21h
cmp al, 13 ; Check for Enter key
je input_done
sub al, '0'
cmp al, 10
jnb input_loop
mov [di], al ; Store [0,9]
inc di
loop input_loop
input_done:
mov [di], al ; Is terminator or harmless garbage
mov di, offset buffer
mov si, 10 ; CONST divider 10
mov cx, 5 ; Max 5 digits
xor bx, bx ; Have BH=0
xor ax, ax ; Result
convert_loop:
mov bl, [di]
cmp bl, 13 ; Check for end of buffer
je convert_done
imul si ; AX * 10 -> DX:AX
add ax, bx ; Plus newest digit
inc di
loop convert_loop
convert_done:
ret
input_number endp