汇编:在不破坏 ADC 循环中的 CF 的情况下增加 2(或更大的数字)?
Assembly: Increment by 2 (or larger number) without destroying CF in an ADC loop?
我正在尝试在 Windows 中测试 TDM-GCC 64 位汇编中的加法函数。前段时间我搜索了这方面的资源,发现了一个与此类似的代码(我做了一些更改以在 TDM-GCC 中编译它)。
typedef struct
{
int size;
__uint64_t uints[130];
} BigInteger;
void add(BigInteger *X, BigInteger *Y); // X += Y
// %rcx holds address of X, and %rdx holds address of Y apparently.
// calc.s - assembly file
.globl add
add:
movq 8(%rdx), %rax
addq %rax, 8(%rcx)
movq 16(%rdx), %rax
adcq %rax, 16(%rcx)
movq 24(%rdx), %rax
adcq %rax, 24(%rcx)
... ...
第一个汇编代码有效。缺点是即使对于小数字,它也需要与计算最大尺寸一样长的时间。因此,我改为检查 X 和 Y 的大小,并放置一个具有大小条件的循环,这样如果 X 和 Y 不大,它就不必总是添加整个数组。
...
// %r13 holds X addr, %r14 holds Y addr.
addq , %r13 // I have tried incq %r13
addq , %r14 // I have tried incq %r14
movq (%r14), %rax
addq %rax, (%r13)
decl %ecx
cmpl [=11=], %ecx
je .add4
.add3:
addq , %r13 // I have tried incq %r13
addq , %r14 // I have tried incq %r14
movq (%r14), %rax
adcq %rax, (%r13)
loop .add3
.add4:
...
但我太简单了,以为使用 ADDQ 运算符向 X 和 Y 的地址 (%r13, %r14) 添加 8 个字节就可以遍历数组.这里的问题是,如果我像这样使用 ADDQ 运算符,它会将进位标志重置为 0,因此使用进位 (.add3) 计算加法的整个循环就会崩溃。我尝试使用
incq %r13
认为 incq 的工作方式类似于在 C++ 中递增一个指针,它知道它应该移动多少字节。但这只会将寄存器值增加 1,而不是我认为它会移动的 8。
所以我的问题是:
有没有办法在汇编中以大于 1 的数字递增寄存器,或者在不触及进位标志的情况下进行加法? (不是add,adc因为他们两个最后都设置了carry flag)
使用寄存器+偏移量加载有效地址
lea rax,[rax+8] ;add 8 to rax
我正在尝试在 Windows 中测试 TDM-GCC 64 位汇编中的加法函数。前段时间我搜索了这方面的资源,发现了一个与此类似的代码(我做了一些更改以在 TDM-GCC 中编译它)。
typedef struct
{
int size;
__uint64_t uints[130];
} BigInteger;
void add(BigInteger *X, BigInteger *Y); // X += Y
// %rcx holds address of X, and %rdx holds address of Y apparently.
// calc.s - assembly file
.globl add
add:
movq 8(%rdx), %rax
addq %rax, 8(%rcx)
movq 16(%rdx), %rax
adcq %rax, 16(%rcx)
movq 24(%rdx), %rax
adcq %rax, 24(%rcx)
... ...
第一个汇编代码有效。缺点是即使对于小数字,它也需要与计算最大尺寸一样长的时间。因此,我改为检查 X 和 Y 的大小,并放置一个具有大小条件的循环,这样如果 X 和 Y 不大,它就不必总是添加整个数组。
...
// %r13 holds X addr, %r14 holds Y addr.
addq , %r13 // I have tried incq %r13
addq , %r14 // I have tried incq %r14
movq (%r14), %rax
addq %rax, (%r13)
decl %ecx
cmpl [=11=], %ecx
je .add4
.add3:
addq , %r13 // I have tried incq %r13
addq , %r14 // I have tried incq %r14
movq (%r14), %rax
adcq %rax, (%r13)
loop .add3
.add4:
...
但我太简单了,以为使用 ADDQ 运算符向 X 和 Y 的地址 (%r13, %r14) 添加 8 个字节就可以遍历数组.这里的问题是,如果我像这样使用 ADDQ 运算符,它会将进位标志重置为 0,因此使用进位 (.add3) 计算加法的整个循环就会崩溃。我尝试使用
incq %r13
认为 incq 的工作方式类似于在 C++ 中递增一个指针,它知道它应该移动多少字节。但这只会将寄存器值增加 1,而不是我认为它会移动的 8。
所以我的问题是:
有没有办法在汇编中以大于 1 的数字递增寄存器,或者在不触及进位标志的情况下进行加法? (不是add,adc因为他们两个最后都设置了carry flag)
使用寄存器+偏移量加载有效地址
lea rax,[rax+8] ;add 8 to rax