我无法理解一些指令,例如
sub
指令,根据手册将其定义为 AddWithCarry
操作,其中进位设置为 1
的硬编码值:
bits(datasize) result;
bits(datasize) operand1 = if n == 31 then SP[]<datasize-1:0> else X[n, datasize];
bits(datasize) operand2;
operand2 = NOT(imm);
(result, -) = AddWithCarry(operand1, operand2, '1');
if d == 31 then
SP[] = ZeroExtend(result, 64);
else
X[d, datasize] = result;
AddWithCarry
操作定义如下:
(bits(N), bits(4)) AddWithCarry(bits(N) x, bits(N) y, bit carry_in)
integer unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
integer signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
bits(N) result = unsigned_sum<N-1:0>; // same value as signed_sum<N-1:0>
bit n = result<N-1>;
bit z = if IsZero(result) then '1' else '0';
bit c = if UInt(result) == unsigned_sum then '0' else '1';
bit v = if SInt(result) == signed_sum then '0' else '1';
return (result, n:z:c:v);
是否始终将
1
作为进位传递并根据 AddWithCarry
的定义进行查找,使减法运算也从所有操作中减去 1
?
我知道当我们写这样的东西时:
sub sp, sp, #0x20
我们实际上只从
sp
中减去 32 个字节,那么这个操作中的进位位是怎么回事?
一开始这也让我很困惑。关键是前面的那行:它不是您所期望的
operand2 = -imm
,而是 operand2 = NOT(imm)
,即按位非(补码)。在二进制补码算术中,您可以轻松检查NOT(imm) = -imm - 1
。因此,进位设置为 1 可有效计算 x + (-imm - 1) + 1
,这确实是 x - imm
。