使用AT&T汇编实现按2的n次幂整除(向零取整)
问题分析与正确实现
你当前的代码完全偏离需求核心:
- 未对输入的第一个参数
x(x86-64调用约定中存储在%rdi寄存器)做任何运算,反而修改了第二个参数n(%esi),逻辑完全错误 - 直接使用
sar右移负数时,会向负无穷取整,不符合题目要求的向零取整规则(比如-33 >> 4用sar得到的是-3,但题目要求结果是-2)
正确实现思路
针对2的幂次的向零取整除法,需区分正负处理:
- 正数:直接算术右移
n位即可(正数的算术/逻辑右移结果一致) - 负数:先加上
(2ⁿ - 1),再算术右移n位,抵消补码右移带来的负方向偏移,实现向零取整
AT&T语法汇编实现
.global dividePower2 dividePower2: # x存储在%rdi,n存储在%rsi testq %rdi, %rdi # 检查x的符号位 jns .L_shift # 若x非负,直接跳转到移位步骤 # 处理负数:计算2^n -1并加到x上 movl $1, %eax # eax初始化为1 movl %esi, %cl # 将n移入cl(移位指令用cl存计数) shll %cl, %eax # eax = 2^n subl $1, %eax # eax = 2^n -1 addq %rax, %rdi # x += (2^n -1) .L_shift: movl %esi, %cl # 将n移入cl sarq %cl, %rdi # x >>= n(算术右移) movq %rdi, %rax # 将结果放入返回寄存器%rax ret
验证示例
- 输入
dividePower2(15,1):15为非负数,直接右移1位得7,符合预期 - 输入
dividePower2(-33,4):-33为负数,计算2^4-1=15,-33+15=-18,右移4位得-2,符合预期
内容的提问来源于stack exchange,提问作者Aidan M
相关产品推荐
相关产品推荐

