请帮我这个程序!我花了很多时间阅读文档,但我不太明白为什么我的代码不起作用。它只是一个基本的计算器,这是我到目前为止所拥有的。在第二种方法之后,它们都不起作用。谢谢!
int calc (int op1, int op2, int opcode)
{
__asm
{
mov eax, 0 ; zero out the result
mov ebx, opcode ; move opcode to ebx for comparison
cmp ebx, 0x01 ; check for ADD
jne sub_2 ; jump if not 2 to sub
mov eax, op1 ; move op1 into eax
add eax, op2 ; add op2 into eax
jmp done ; jump to done
sub_2:
cmp ebx, 0x02 ;
jne mul_3 ;jump if not 3 to mul
mov eax, op1 ;move op1 into eax
sub eax, op2 ;subtract op2 into eax
jmp done ; jump to done
mul_3:
cmp ebx, 0x03 ;
jne div_4 ; jump to div_4 if ot 3
mov eax, 0 ; move 0 into eax
mov ecx, op1 ; move op1 into ecx
mov edx, op2 ; move op2 into edx
L2:
//and ecx, 01 ; I'm not sure if I should do this to check the lowest bit
jnc no_add ; check if lowest bit is 0, if yes jump to no_add
add eax, edx ; add edx to the result which is eax
no_add:
rcr ecx, 1 ; rotate with carry to right 1 bit ecx
shl edx, 1 ; shift left edx 1 bit
jnz L2 ; jump back to loop if edx is not 0
jmp done
done:
}
答案 0 :(得分:1)
在装配中;所有错误都可以归类为:
例如,这些注释没有描述一个合理的添加算法,只有单独阅读评论才能明白这个错误:
;Do addition
mov eax,op1 ;eax = operand1
sub eax,op2 ;eax = operand1 - operand2 = result
再举一个例子,这些说明与评论不符,从每条指令与评论比较中就会发现错误:
;Do addition
mov eax,op1 ;eax = operand1
add eax,op2 ;eax = operand1 + operand2 = result
这种做法使得查找错误变得容易得多,因为您可以更轻松地检查算法,然后(如果/当您确定算法正确时)检查实现更容易。
对于您的代码,注释不会描述理智的算法,并且说明与其注释不符;所以你的代码是100%的错误。
请注意,汇编语言不是一种语言。每个CPU都有一种或多种不同的汇编语言方言。对于80x86,有两组汇编语言(AT& T语法和Intel语法);在每一组中都有不相容的方言。例如;为NASM / YASM编写的代码通常无法在FASM或MASM上正确汇编(即使它们都使用Intel语法);因为指令(在某些情况下是操作数)之类的东西是不同的。
例如,我在你的代码中看到mov eax,op1
,因为我习惯了NASM语法,我认为这是一个错误(使用地址而不是地址上的数据),应该是{{1相反。但是,对于MASM(喜欢尝试使其看起来更像高级语言中的变量)mov eax,[op1]
可能是完全正确的而不是错误。因为你没有说明你正在使用哪种方言,我不知道这是不是一个错误。
当你拥有一长串分支时,使用跳转表会更有效(并且更容易阅读/维护代码)。例如(NASM语法):
mov eax,op1