我在x86程序集中编写程序,计算四个等级的平均值。我目前正在使用四个寄存器(RAX
,RBX
,RCX
和RDX
)来保存我的.data
部分中声明的四个等级。我还将quot
,rem
,total
和ans
全部初始化为0.
我的一般方法是将四个寄存器一起添加并将总数存储在total
变量中。我最初只是将总数保留在RAX
,但后来我想将其存储在变量中,以便我可以重复使用RAX
和RDX
。
这是一个好主意还是我只为自己生成更多代码?我将RAX
和RDX
寄存器重置为0,以便我可以将它们用于我的除法计算(总计/ 4)。我正在关注的书是使用RAX
和RDX
寄存器,所以我认为这就是我应该做的。
代码未完成,因此忽略了最后一行的IDIV
。
segment .data
a dq 100
b dq 57
c dq 74
d dq 23
quot dq 0
rem dq 0
total dq 0
ans dq 0
segment .text
global main
main:
mov rax, [a]
mov rbx, [b]
mov rcx, [c]
mov rdx, [d]
add rax, rbx
add rcx, rdx
add rax, rcx
mov [total], rax
mov rax, 0
mov rdx, 0
mov rax, [total]
mov rdx, 0
答案 0 :(得分:5)
没有对错,除非你人为地限制自己的寄存器数量少于可用的寄存器,否则你就会添加操作码并使你的代码膨胀。仅使用编码操作所需的寄存器数量。
但是,如果要求发生变化并且您必须处理100个等级,请考虑将会发生什么。或者1000.或者N ..这可能激发你以不同的方式实现你的逻辑。也许考虑使用堆栈来存储成绩?
PS:从架构的角度来看,这里主要关注的是平衡溢出/恢复寄存器的缓存和操作码开销。这个决定在这里并不适用,因为你泄漏的任何数量的寄存器(手工编码)都应该在L1缓存中。实际上,当你的实现用完了寄存器而你开始不得不添加溢出操作码时。
答案 1 :(得分:2)
通常在性能方面,最好不要访问内存(尤其是L0缓存之外的内存)。
如果你有备用寄存器,暂时将值存储到它中比将它存储到存储器中更便宜(尽管该写入将被缓存并且下次读取将很有可能使用它,所以它不会伤害那么多阅读一些"新的"内存位置)。推送/弹出(堆栈)也是内存,因此将值存储到备用寄存器中也比堆栈上的临时存储更便宜。
然后再次使用算法破坏的寄存器越少,从其他地方调用该代码时,保存/恢复的次数就越少,其中您已经在寄存器中有值,因此资源丰富并且只使用尽可能少的寄存器是个好主意。
关于您的来源:
在您的代码中,mov [total],rax
,mov rax,0
和mov rax,[total]
朝向end的整个三元组可以简化为仅第一条指令,这将更新" total"记忆。然后加载rax
为零,然后用之前的总值加载它,即。删除这两个将只保持rax
中的总值不变。
但是我会更进一步,保存更多的寄存器和浪费的指令,如下所示:
mov rax, [a]
add rax, [b]
add rax, [c]
add rax, [d]
; rax = total (can overflow for large a/b/c/d)
division - signed variant
mov [total], rax ; can be omitted, if you don't need [total] updated
cqo ; sign-extend rax into rdx:rax
; ^ your "mov rdx,0" is bug, as you want "idiv", total of 4x -1 is -4 => rdx should be -1
mov rcx,4
idiv rcx
; only rax, rdx and rcx are modified, [rax, rdx] contains result
除法 - 无符号变体(当a,b,c,d为正数,或者至少为#34;总数为#34;
mov [total], rax ; can be omitted, if you don't need [total] updated
; calculate remainder after division by 4 by copying low 2 bits of "total" into rdx
mov edx,eax ; 32b mov clears upper 32b of rdx!
and edx,3 ; bit 0 and bit 1 of total is remainder after unsigned /4
; calculate quotient of usigned rax/4 (by shifting rax two bits right)
shr rax,2
; only rax, and rdx are modified, [rax, rdx] contains result