我正在学习NASM,并正在制作一个简单的程序,通过移位和添加来增加任何用户输入变量。
我遇到了一系列问题:由于某种原因,我的被乘数是以一个单词可以容纳的最大数据值给出的。此外,我的答案,如果程序应该到那么远,几乎总是错误的(即使我相信我的算法是正确的!)。
extern printf
extern scanf
section .data
message: db "Enter your multiplicand: "
message_L: equ $-message
message2: db "The number you entered is: %d ", 10, 0
message2_L: equ $-message2
message3: db "Enter your multiplier: "
message3_L: equ $-message3
message4: db "Your multiplier is: %d ", 10, 0
message4_L: equ $-message4
message5: db "The product of this multiplication is: %d ", 10, 0
mesasge5_L: equ $-message5
fmt1: db "%d", 0
section .bss
multiplicand: resw 1
multiplier: resw 1
product: resw 1
section .text
global main
scanInt:
push ebp
mov ebp, esp
sub esp, 2
lea eax, [ebp-2]
push eax
push dword fmt1
call scanf
mov ax, word[ebp-2]
mov esp, ebp
pop ebp
ret
main:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov eax, 4
mov ebx, 1
mov ecx, message
mov edx, message_L
int 80h
call scanInt
mov word[multiplicand], ax
mov word[product], ax
jmp print1
main2:
mov eax, 4
mov ebx, 1
mov ecx, message3
mov edx, message3_L
int 80h
call scanInt
mov word[multiplier], ax
jmp print2
main3:
mov ax, word[multiplicand]
jmp check
check:
cmp word[multiplier], 2
jz printAnswer
ror [multiplier], 1
shl word[multiplier], 1
jc carry
shr word[multiplier], 1
shr word[multiplier], 1
shl word[product], 1
jmp check
carry:
add word[product], ax
shr word[multiplier], 1
clc
jmp check
endLoop:
mov eax, 1
mov ebx, 0
int 80h
printAnswer:
push ebp
mov ebp, esp
push word[product]
push dword message5
call printf
add esp, 12
mov esp, ebp
pop ebp
jmp endLoop
print1:
push ebp
mov ebp, esp
push dword[multiplicand]
push dword message2
call printf
add esp, 12
mov esp, ebp
pop ebp
jmp main2
print2:
push ebp
mov ebp, esp
push dword[multiplier]
push dword message4
call printf
add esp, 12
mov esp, ebp
pop ebp
jmp main3
答案 0 :(得分:1)
我认为您的主要问题来自于使用word
变量。在堆栈上创建一个双字节缓冲区,并调用scanf
来读取它几乎肯定是个问题。在32位代码中推送word
是“合法的”,但可能会导致问题。在一个实例中,您使用两个变量调用printf
,然后调用add esp, 12
。将它们全部dword
组成,并将堆栈操作保持为四字节块。我认为这将解决你的大多数问题。
手册页明确建议不要将高级缓冲I / O函数与低级函数混合(printf
,scanf
,fopen()
,fread()
,{ {1}}等是高级函数,fwrite()
,open()
,read()
...系统调用是低级函数。我不认为这会导致你的任何问题,但它可能导致奇怪的结果。例如,在刷新缓冲区之前,write()
不会打印任何内容。使用换行符结束或使用其他高级I / O功能将刷新缓冲区。例如,printf
没有。我会坚持一个或另一个。