左移指令和右称指令的种类及作用:
左移指令作用:左移指令将操作数的bit位向左移动n位,空出来的位用0填充。
左移指令包含sal和shl,这两条指令的作用是相同的,空出来的位用0填充。
其中左移sal的指令用法:
.section .text .global _start _start: movb $0b11111111, %al #8字节 salb $3, %al movw $0b11111111, %ax #16字节 salw $3, %ax movl $0b11111111, %eax #32字节 sall $3, %eax movq $0b11111111, %rax #64字节 salq $3, %rax
其中左移shl的指令用法:
.section .text .global _start _start: movb $0b11111111, %al #1个字节 shlb $3, %al movw $0b11111111, %ax #2个字节 shlw $3, %ax movl $0b11111111, %eax #4个字节 shll $3, %eax movq $0b11111111, %rax #8个字节 shlq $3, %rax
右移指令作用:右移指令将操作数的bit位向右移动n位,sar执行算术移位(填上符号位),而shr执行逻辑移位(填上0).移位操作的目的操作数可以是一个寄存器或是一个存储器位置。
右移指令sar和shr
其中右移sar的指令用法,sar右移会用符号位填充,如果符号位是1,就填充1,如果是0就填充0。
.section .text .global _start _start: movb $0b01111111, %al #符号位是0 sarb $3, %al movb $0b11111111, %al #符号位是1 sarb $3, %al movw $0x7FFF, %ax sarw $3, %ax movw $0xFFFF, %ax sarw $3, %ax movl $0x7FFFFFFF, %eax sarl $3, %eax movl $0xFFFFFFFF, %eax sarl $3, %eax movq $0x7FFFFFFFFFFFFFFF, %rax sarq $3, %rax movq $0xFFFFFFFFFFFFFFFF, %rax sarq $3, %rax
其中右移sar的指令用法,shr始终填充0
.section .text .global _start _start: movb $0b01111111, %al #符号位是0 shrb $3, %al movb $0b11111111, %al #符号位是1 shrb $3, %al movw $0x7FFF, %ax shrw $3, %ax movw $0xFFFF, %ax shrw $3, %ax movl $0x7FFFFFFF, %eax shrl $3, %eax movl $0xFFFFFFFF, %eax shrl $3, %eax movq $0x7FFFFFFFFFFFFFFF, %rax shrq $3, %rax movq $0xFFFFFFFFFFFFFFFF, %rax shrq $3, %rax
c语言中的同类操作符:
练习:
练习题摘自《c和指令》第5章操作符和表达式
3.请编写函数
unsigned int reverse_bits(unsigned int value);
这个函数的返回值是把value的二进制位模式从左到右变换一下后的值。例如,在32位机器上,25这个值包含了下列各个位:
00000000000000000000000000011001
10011000000000000000000000000000
汇编code:
.section .text .global reverse_bits .type reverse_bits, @function reverse_bits: xorl %eax, %eax movl $32, %ecx reverse_bits_start: cmpl $0, %ecx je reverse_bits_end shll $1, %eax movl %edi, %esi andl $1, %esi orl %esi, %eax shrl $1, %edi decl %ecx jmp reverse_bits_start reverse_bits_end: ret
c测试代码
#include <stdio.h> #include <assert.h> extern int reverse_bits(unsigned int ui); int main() { unsigned u; u = reverse_bits(0x7fffffff); assert(u == 0xfffffffe); printf("u(%x)\n", u); u = reverse_bits(0x00ffffff); assert(u == 0xffffff00); printf("u(%x)\n", u); u = reverse_bits(0xffff00ff); assert(u == 0xff00ffff); printf("u(%x)\n", u); u = reverse_bits(0xffffff00); assert(u == 0x00ffffff); printf("u(%x)\n", u); u = reverse_bits(0xff00ffff); assert(u == 0xffff00ff); printf("u(%x)\n", u); return 0; }
4.编写一组函数,实现位数组。函数的原型应该如下:
void set_bit(char bit_array[], unsigned bit_number); void clear_bit(char bit_array[], unsigned bit_number); void assign_bit(char bit_array[], unsigned bit_number); int test_bit(char bit_array[], unsigned bit_number);
每个函数的第1个参数是个字符数组,用于实际存储所有的位。第2个参数用于标识需要访问的位。函数的调用者必须确保这个值不要太大,以至于超出数组的边界,第1个函数把指定的位设置为1, 第2个函数则把指定的位清零。如果value的值为0,第3函数把指定的位清0,否则设置为1.至于最后一个函数,如果参数中指定的位不是0,函数就返回真,否则就返回假。
汇编code:
时间: 2024-10-23 13:55:58