汇编中如何用异或操作翻转数字的n个高位/低位?
汇编中用XOR翻转指定位数的高低位及掩码生成方法
核心逻辑
异或(XOR)的核心特性是:0 XOR 1 = 1,1 XOR 1 = 0。要翻转某几位,只需让这些位与1异或,其余位与0异或,关键就是生成对应位置全为1的掩码。
掩码生成规则
1. 低位n位掩码
低位n位全1的掩码公式固定:(1 << n) - 1
- 示例:n=2时,
1 << 2得到二进制100,减1后为011(十进制3),对应4位数字场景的0011、6位场景的000011。
2. 高位n位掩码
分两种场景处理:
寄存器固定宽度场景(如x86的32/64位、ARM的32位)
利用寄存器的固定宽度生成掩码:
- 先取该宽度下的全1值(如32位的
0xFFFFFFFF),再右移(寄存器宽度 - n)位,得到高位n位全1的结果。 - 示例:32位寄存器、n=2时,
0xFFFFFFFF右移30位,得到0xC0000000(二进制最高两位为1,其余为0)。
任意长度数字场景
必须先获取数字的总位数m,再用公式:((1 << n) - 1) << (m - n)
- 示例:6位数字(m=6)、n=2时,
(1<<2)-1=3(二进制11),左移6-2=4位,得到110000。
汇编实现示例(x86 32位汇编)
翻转低位n位
假设n存在ecx,目标数在eax:
mov ebx, 1 shl ebx, cl ; ebx = 1 << n dec ebx ; ebx = (1<<n)-1,低位n位掩码 xor eax, ebx ; 翻转eax的低位n位
翻转高位n位(32位寄存器场景)
假设n存在ecx,目标数在eax:
mov ebx, 0xFFFFFFFF mov edx, 32 sub edx, ecx ; edx = 32 - n shr ebx, dl ; ebx = 全1右移(32-n)位,高位n位掩码 xor eax, ebx ; 翻转eax的高位n位
任意长度数字的高位n位翻转(需先计算总位数)
假设目标数在eax,n在ecx,先计算总位数m存入edx:
; 计算正整数eax的总位数m mov edx, 0 mov ebx, eax count_bits: test ebx, ebx jz count_done inc edx shr ebx, 1 jmp count_bits count_done: ; 生成高位n位掩码 mov ebx, 1 shl ebx, cl dec ebx ; ebx = (1<<n)-1 mov ecx, edx sub ecx, cl ; ecx = m - n shl ebx, cl ; ebx = ((1<<n)-1) << (m-n),高位n位掩码 xor eax, ebx ; 翻转高位n位
总结
- 低位n位掩码:固定公式
(1 << n) - 1,与数字总位数无关。 - 高位n位掩码:
- 固定宽度寄存器场景:用全1值右移
(寄存器宽度 - n)位生成。 - 任意长度数字场景:先获取总位数m,再通过
((1 << n) - 1) << (m - n)生成。
- 固定宽度寄存器场景:用全1值右移
内容的提问来源于stack exchange,提问作者Stevie Roberts
相关产品推荐
相关产品推荐

