我的教授给了我一个转换,将这个C代码转换为汇编代码
int k = 0, S = 0;
for (k=0; k<100; k++)
{
if (k%2 == 0)
S += k;
else
S -= k;
}
装配只是我课程的一小部分,所以我们还没有涉及很多技术部分.我唯一的问题是模数部分,我们只采用了除法,从未学过如何使用模数.这是我进入我的工作
MOV CX, 0; counter
MOV AX, 0; This represents S, we haven't learned how to declare variables in assembly, so we use registers instead)
Loop1:
CMP [Haven't done the modulus condition]
JE iftrue
JNE ifwrong
iftrue:
ADD AX, CX
INC CX
CMP CX, 99
JL Loop1
ifwrong:
SUB AX, CX
INC CX
CMP CX, 99
JL Loop1
你能帮我填写第一个条件吗?如何在比较中使用模数并检查余数是否为0?
PS:我还没学会如何在循环中做条件,所以iftrue/ifwrong部分只是我的快速即兴创作,我不知道它是否有效.那部分可以以更好的形式完成吗?
1> Mike Nakis..:
教授通常不会提供涉及您尚未学习的内容的作业.对于外部观察者(例如任何阅读此问题的人),大多数机会是你没有注意到,或者你没有意识到正在解释的是实现模数运算的一种方法.
x86组件中的模数可以通过除以两个数来获得.你把divident放在某个寄存器中,你执行一些提供除数的指令,并且在指令执行后,一些寄存器接收商,另一个寄存器接收余数.但那是无关紧要的,因为你可能还没有学过分裂操作,这没关系,因为我们不打算使用除法.
在x86程序集中(以及任何其他程序集中),您可以非常轻松地计算除法的余数除以2的幂,而无需使用除法运算.2是2的幂.(2的1次方)
实际上,在2的情况下,事情变得更加简单,因为我希望你同意,除以2的其余部分只有两个可能的结果:1或0,这是不言而喻的.
您可能还记得,二进制数字看起来像这样:0011101010
最左边的位是最重要的位,最右边的位是最低位.并且,表示数字的二进制系统的基本属性是,如果将该数字除以2,则数字的最低有效位始终表示您将接收的余数.(就像在十进制系统中一样,最右边的数字表示如果将该数字除以10,您将收到的余数.)
因此,您需要做的就是将最低有效位与数字隔离开来.这将是0或1,它将表示数字除以2的余数.
"确切地说,如何实现这一目标,是留给学生的锻炼."
(尝试一下,如果你不能这样做,请发布另一个stackoverflow问题.)
关于JE/JNE部分,它实际上是错误的,因为当CX不再小于99时,JL Loop1
指令将落到ifwrong:
标签上,这不是你想要的.你应该按如下方式重写它:
JE iftrue
ifwrong: ;unnecessary label, for illustration purposes only
SUB AX, CX
JMP after
iftrue:
ADD AX, CX
JMP after ;unnecessary instruction, for illustration purposes only.
after:
INC CX
CMP CX, 99
JL Loop1
请注意,您并不想要,ADD AX, CX
并且SUB AX, CX
,您想要ADD AX, MM
和SUB AX, MM
,MM
CX模数2 在哪里,以及您仍在计算如何计算的过程中.
另请注意,我没有担心CMP CX, 99
后面JL Loop1
是否正确,你没有问过这个,你可能会在以后遇到它,但它应该很容易弄明白.
`SHR MM,1`是一种方法,但是你会暂时需要一个额外的寄存器(比方说,DX),因为你不想转移CX,因为你不想破坏它的价值.Aki Suihkonen建议的"TEST CX,1"指令是一个更好的选择,因为它在不改变任何东西的情况下测试第0位.`MOV MM,CX`不起作用,因为`MOV`指令不修改标志寄存器,因此不会设置奇偶校验标志.