我们的任务是比较整数值并打印出适当的提示以显示哪些值更大。
我在下面的代码分别将'i'和'j'初始化为5和4。目标是比较“变量”而不是立即值本身。所以在这个例子中,我把'i'和'j'放在cmp中,而不是5和4。
global _main
extern _printf, _system
section .text
_main:
; clear screen
push clr
call _system
add esp, 4
;Test prints out i. Successfully does the job.
push dword [i] ; why did it work here and not in *cmp*?
push prompt2
call _printf
add esp, 8
;compare values and do a conditional jump.
CMP dword [i], dword [j] ; compares values stored in i and j. i and j are base 10 nums. This is where the error appears.
JG igreat ; jumps if i is greater than j.
JL jgreat ; jumps if j is greater than i.
JE eks ; jumps if i and j are equal.
ret ; as a measure, this ends the code.
igreat: ; prints out a prompt if i is greater than j.
push dword [j]
push dword [i]
push ibig
call _printf
add esp, 16
ret
jgreat: ; prints out a prompt if j is greater than i.
push dword [i]
push dword [j]
push jbig
call _printf
add esp, 16
ret
eks: ; prints out a prompt if i is equal to j.
push dword [i]
push dword [j]
push ex
call _printf
add esp, 16
ret
last: ; terminates the code
ret
section .data
clr db "cls",0
i dd 5 ; i is initialized to 5
j dd 4 ; j is initialized to 4
prompt2 db "Value is %d",13,10,0
ibig db "Test 1. Comparisons: %d is bigger than %d",13,10,0
jbig db "Test 2. Comparisons: %d is bigger than %d",13,10,0
ex db "Test 3. Comparisons: %d is bigger than %d",13,10,0
我可能提出两个问题:
请注意,我运行的是Windows 8 Intel 32位,此代码已经在运行在DoSBox中的NASM中进行了“编译”,而在CMD中运行了GCC。
我是一个初学者,非常感谢任何帮助。谢谢!
答案 0 :(得分:6)
CMP
无法比较两个内存位置。它可以将寄存器与寄存器,常量或存储器进行比较,并且可以将存储器位置与常量或寄存器进行比较。这就是您收到错误并且正确的原因。您必须将其中一个的值存储到寄存器中然后进行比较。
该计划之所以没有回应"是因为你弄乱了ESP
。你把东西推到堆栈,调用_printf
然后由于某种原因向上移动ESP
16个字节。然后,RET
将跳转到堆栈中的第一个值,并且我确定它不正确。
您应该在启动时以及在返回还原ESP
和EBP
时将ESP
值存储到RET
。