汇编语言---位操作指令(gcc内联汇编测试)

目录

一:逻辑与指令AND

二:逻辑或指令OR

三:逻辑异或指令XOR

四:逻辑非指令NOT(按位取反)

五:测试指令TEST

六:移位指令(shift)

七:算术移位指令

八:循环移位指令(rotate)


位操作类指令

逻辑运算指令:
    AND OR XOR NOT TEST
移位指令:
    逻辑、算术移位指令:
    SHL SHR SAL SAR
    循环、带进位循环移位指令:
    ROL ROR RCL RCR
符号解释:
    &:按位与 |:按位或 ^:按位异或
    reg:寄存器 imm:立即数 mem:内存变量

注意这些指令对标志位的影响

 

一:逻辑与指令AND

and reg,imm/reg/mem     ;reg←reg & imm/reg/mem
and mem,imm/reg           ;mem←mem & imm/reg

AND指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义
可以用来置某位某些位为0 ,不影响其他位
例:

int and_asm(int a1, int a2)
{
        register int result = 0;
        asm volatile(
                "and %1,%2  \n\t"
                "mov %2, %0 \n\t"
                :"=&a"(result)       
                :"b"(a1),"c"(a2)
                :"cc");
        return result;
}

printf("0b0001 & 0b0011 = %d\n", and_asm(0b0001, 0b0011));
printf("0b0000 & 0b0011 = %d\n", and_asm(0b0000, 0b0011));
printf("0b1111 & 0b1111 = %d\n", and_asm(0b1111, 0b1111));

结果:
0b0001 & 0b0011 = 1
0b0000 & 0b0011 = 0
0b1111 & 0b1111 = 15

二:逻辑或指令OR

or reg,imm/reg/mem         ;reg←reg | imm/reg/mem
or mem,imm/reg            ;mem←mem | imm/reg

OR指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义
可以用来置某位某些位为1,不影响其他位

三:逻辑异或指令XOR

xor reg,imm/reg/mem     ;reg←reg ^ imm/reg/mem
xor mem,imm/reg           ;mem←mem ^ imm/reg

XOR指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义
可以用来求反某些位,不影响其他位

四:逻辑非指令NOT(按位取反)

not reg/mem             ;reg/mem←~reg/mem

NOT指令不影响标志位
例:

int not_asm(int a1)
{
        register int result = 0;
        asm volatile(
                "not %1     \n\t"
                "mov %1, %0 \n\t"
                :"=&a"(result)
                :"b"(a1)
                :"cc");
        return result;
}

printf("0b0000 = %x\n", not_asm(0b0000));
printf("0b0101 = %x\n", not_asm(0b0101));
printf("0b1111 = %x\n", not_asm(0b1111));

结果:从测试结果可以分析得出逻辑非即按位取反
0b0000 = ffffffff
0b0101 = fffffffa
0b1111 = fffffff0

五:测试指令TEST

对两个操作数执行逻辑与运算,结果不回送到目的操作数

test reg,imm/reg/mem        ;reg & imm/reg/mem
test mem,imm/reg            ;mem & imm/reg

TEST指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义
TEST指令通常用于检测一些条件是否满足,但又不希望改变原操作数的情况

例:测试某一位为0或1

int test_asm(int a1, int a2)
{
        register int result = 0;
        asm volatile(
                "test %2,%3     \n\t"
                "jz zero        \n\t"
                "sbb %0,%0      \n\t"
                "or $1,%0       \n\t"
                "zero:"
                :"=&a"(result)  /*对应%0*/
                :"0"(result),"b"(a1),"c"(a2) /*对应%1,,%2, %3,其中%1=%0参数*/
                :"cc");
        return result;
}

printf("0b0000 & 0b0000 = %x\n", test_asm(0b0000, 0b0000));
printf("0b0101 & 0b0000 = %x\n", test_asm(0b0101, 0b0000));
printf("0b0101 & 0b0101 = %x\n", test_asm(0b0101, 0b0101));

结果:
0b0000 & 0b0000 = 0
0b0101 & 0b0000 = 0
0b0101 & 0b0101 = 1

六:移位指令(shift)

逻辑移位指令

shl reg/mem,1/CL          (Shift Logical Left)
                        ;逻辑左移,最高位进入CF,最低位补0
shr reg/mem,1/CL          (Shift Logical Right)
                        ;逻辑右移,最低位进入CF,最高位补0

七:算术移位指令

sal reg/mem,1/CL          (Shift Arithmetic Left)
                        ;算术左移,最高位进入CF,最低位补0 (同SHL)
sar reg/mem,1/CL          (Shift Arithmetic Right)
                        ;算术右移,最低位进入CF,最高位不变(保证符号位不变)
                        ;SAR也是右移,只不过一直用原来符号位的数来补

移位指令对标志的影响
按照移入的位设置进位标志CF,根据移位后的结果影响SF、ZF、PF
对AF没有定义
如果进行一位移动,则按照操作数的最高符号位是否改变,相应设置溢出标志OF:
如果移位前的操作数最高位与移位后操作数的最高位不同(有变化),则OF = 1;
否则OF = 0。当移位次数大于1时,OF不确定


移位指令的意义

一个数左移1位相当于乘以2,右移1位相当于除以2
逻辑移位适于无符号数的移位处理:逻辑左移一位,相当于无符号数乘2,CF反映进位,逻辑右移一位,相当于无符号数除以2,商在目的操作数中,余数由CF标志反映

算术移位适于带符号数的移位处理:算术左移一位,如果符号位不变,相当于有符号数乘2,否则运算结果不正确,算术右移一位, 相当于有符号数除以2;商在目的操作数中,余数由CF标志反映

 

八:循环移位指令(rotate)

将操作数从一端移出的位返回到另一端形成循环,分成不带进位和带进位,分别具有左移或右移操作循环移位的同时,被移位的那个数也会进入CF

rol reg/mem,1/CL      ;(Rotate Left)  不带进位循环左移
ror reg/mem,1/CL      ;(Rotate Right) 不带进位循环右移

rcl reg/mem,1/CL      ;(Rotate Carry Left)  带进位循环左移 相当于是和CF一起,9位一起进行循环移位
rcr reg/mem,1/CL      ;(Rotate Carry Right) 带进位循环右移

循环移位指令对标志的影响
按照指令功能设置进位标志CF,不影响SF、ZF、PF、AF
如果进行一位移动,则按照操作数的最高符号位是否改变,相应设置溢出标志OF:如果移位前的操作数最高位与移位后操作数的最高位不同(有变化),则OF = 1;否则OF = 0。当移位次数大于1时,OF不确定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值