Aarch64 指令定义为带进位的加法运算

问题描述 投票:0回答:1

我无法理解一些指令,例如

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 个字节,那么这个操作中的进位位是怎么回事?

assembly cpu-architecture arm64 subtraction carryflag
1个回答
0
投票

一开始这也让我很困惑。关键是前面的那行:它不是您所期望的

operand2 = -imm
,而是
operand2 = NOT(imm)
,即按位非(补码)。在二进制补码算术中,您可以轻松检查
NOT(imm) = -imm - 1
。因此,进位设置为 1 可有效计算
x + (-imm - 1) + 1
,这确实是
x - imm

© www.soinside.com 2019 - 2024. All rights reserved.