x86汇编%ax绝对值(abs)实现方案对比:哪种更优?
计算%ax绝对值的两种x86汇编实现对比
延续关于x86汇编abs()实现的讨论,这里聚焦于高效计算%ax寄存器中值的绝对值,整理出两种省略栈管理的实现方案:
算术版实现
absax: cwd xor %dx, %ax sub %dx, %ax ret
该实现通过cwd指令将%ax的符号位扩展到%dx寄存器:当%ax为负数时,%dx会被置为0xFFFF(即-1),此时xor %dx, %ax等价于对%ax按位取反,后续sub %dx, %ax相当于减去-1,本质就是执行neg取反操作;当%ax为正数时,%dx为0,xor和sub操作不会改变%ax的值,最终得到绝对值。
条件版实现
absax: mov %ax, %dx neg %ax cmovs %dx, %ax ret
这个版本的逻辑更直观易懂,也更易记忆:先将%ax的原始值备份到%dx,对%ax执行neg指令(等价于用0减去%ax);如果neg操作后SF(符号标志位)被置1,说明原%ax是正数(正数取反后为负数,SF=1),此时通过cmovs指令将备份在%dx的原始正数替换回%ax;如果SF为0,说明原%ax是负数(取反后得到正数绝对值,SF=0),则保留neg后的结果。这也是GCC偏好的实现方式。
目前能找到的资料大多围绕算术版展开讨论,关于条件版的内容较少,因此希望明确两种方案的优劣,确认条件版是否存在潜在劣势。
注:后续发现原问题的答案中也有条件版的相关讨论,在此致歉,但仍希望深入对比两者的差异。
内容的提问来源于stack exchange,提问作者ugo_capeto
相关产品推荐
相关产品推荐

