汇编总结:左移,右移指令

左移指令和右称指令的种类及作用:

左移指令作用:左移指令将操作数的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

汇编总结:左移,右移指令的相关文章

基于8086CPU微处理器的汇编学习之MOV指令

汇编指令:MOV的作用是往某个寄存器中存入数值. 格式:mov  寄存器名,数值                数值-->寄存器 mov  寄存器A,存器寄B          B-->A PS:必须前后位数匹配,如: mov   ah,bx     ;error   ah is 8 bit,bx is 16 bit mov   ah, bh    ;right    ah and bh all is 8  bit mov   cx,dx     ;right     cx and dx al

基于8086CPU微处理器的汇编学习之ADD指令

ADD指令: 把两个数值相加,将结果放到第一个寄存器里面. 格式: ADD  寄存器名,数值 ADD  寄存器名,寄存器名 add ax,11 add bx,22 PS:清空数据: mov ax,0000 两者数值的存储容量位数要匹配 ----------------------------------------------------------------------------------------------- 用汇编语言编写一个小程序:1122H + 9000H +   AC02H

16位汇编第八讲指令第四讲

16位汇编第八讲指令第四讲 一丶串操作类指令 1.什么是串操作? 1.串操作指令是8086指令系统中比较独特的一类指令,采用比较特殊的数据串寻址方式,在操作主存连续区域 的数据是,特别好用.因而比较常用 简而言之,就是内存中的一段数据,拷贝/读取/修改... 到另一块另内存 重点掌握  MOVS  STOS  LODS CMPS SCAS REP 2.串操作的简介 1.串操作指令的操作数,是驻村中连续存放的数据串(String 注意string表示串的意思)--也就是一段数据在内存中 是连续的,

关于 C/C++左移右移运算符 的总结

一.概述 本文是根据整合网上资料与相关博文总结出来的关于[ C/C++左移右移运算符 ]的知识. 二.正文 (1)结合图示篇,更加简单明了. 移位运算包含“逻辑移位”(logical shift)和“算术移位”(arithmetic shift). 逻辑移位:移出去的位丢弃,空缺位(vacant bit)用 0 填充. 算术移位:移出去的位丢弃,空缺位(vacant bit)用“符号位”来填充,所以一般用在右移运算中. c++中,整数分有符号数和无符号数两种,对于这两种数做左移.右移运算,稍有区

jQuery实现左移右移

1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>完成左移右移</title> 5 <script src="jquery.js"></script> 6 <style type="text/css"> 7 table{background-color:purple;} 8 input{backgr

EASYUI- EASYUI左移右移 GRID中值

EASYUI左移右移 GRID中值 $("#addAll").click(function(){ var ids = []; var names = []; var srcrows = $('#sourceTable').datagrid('getSelections'); if(srcrows.length == 0 ){ Sys.InfoShow("请选择要移动的记录!"); return; } var id;var name; for(var srci=src

嵌入式C开发---用循环实现左移右移

//将n左移m位 int byte_to_left_move(int n , int m) { int i , ret = 1 ; if(n == 0 || n < 0) { return ; } if(n == 1) { for(i = 0 ; i < m ; i++) ret *= n * 2 ; } if(n > 1) { for(i = 0 ; i < m ; i++) ret *= n ; } return ret ; } //将n右移m位 int byte_to_rig

【C#】关于左移/右移运算符的使用

吐槽先~为什么我的老师大学时候没教过我这东西  - -. 继续送栗子: 比如 “(1+2)<<3” 你们猜等于几~ Debug.Log((1+2)<<3)之后输出的是“24”. 为什么呢~ 因为呀因为呀  “ “左移/右移” 是指对应的二进制向左右移位,执行1+2=3,就变成了3<<3.即:把3对应的二进制向左移3位. 3对应的二进制:11   向左移3位变成 11000 二进制11000不就是十进制的24嘛~~~” 继续拓展一下思维 3>>1<<

GNU汇编逻辑或算数左移右移

lsl 左移 .text .global  _start _start: mov r1,#0b1 mov r1,r1,lsl#2 ROR循环右移 .text .global  _start _start: mov r1,#0b11 mov r1,r1,ror#1 原文地址:https://www.cnblogs.com/qifei-liu/p/10175580.html