我正在尝试使用AT&T / GAS语法将此for循环从C转换为汇编:

for(int j = i; i*j < N; j++) {
    A[i*j] = 0;
}


我将我存储在%eax中,将j存储在%ebx中。我遇到的问题是实际上将i和j相乘,因为指令imul“ reg32”,“ reg32”将结果存储在第二个寄存器中,我显然不希望这样做。我想要的是将结果存储在另一个寄存器中的能力,例如说%ecx,然后使用它来访问索引i * j处的数组中的值。

当我查看指令imul的用法时,似乎实际上无法将两个寄存器相乘并将结果存储在第三个寄存器中。当然,我可以做一个循环并做一些加法运算,等等,但这似乎无效,而且不是解决此问题的方法。请注意,我是汇编语言的新手(仅使用了几天),因为我们刚开始在我的CS课程中学习基础知识。

TL; DR

乘以这样的两个寄存器中存储的值的最佳方法是什么:%eax *%ebx =%ecx?

最佳答案

x86是两个操作数体系结构,其中大多数指令采用两个操作数,并覆盖其中一个。如果要将结果写入第三个操作数而不是覆盖源操作数之一,则标准解决方案是先将其中一个操作数移动到目标,然后将目标与两个操作数指令一起使用。例如,要将eaxebx相乘,然后将结果放在ecx中,您可以

mov %ebx, %ecx
imul %eax, %ecx


尽管正如其他人指出的那样,对于您的循环,最好完全放弃乘法,而要意识到您可以使用加法。你的循环

for (int j = i; i*j < N; j++) {
    A[i*j] = 0;
}


可以改写成

A_ = A + i * i;
N_ = N - i * i;
for (j = 0; j < N_; j += i)
    A_[j] = 0;


在循环内不需要乘法。

关于assembly - 在AT&T汇编中是否有一种简单的方法可以将两个寄存器相乘:%eax *%ebx =%ecx,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57910735/

10-09 01:59