为什么SHL和SAL相同

2024-03-06 19:38
文章标签 相同 sal shl

本文主要是介绍为什么SHL和SAL相同,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1 移位指令简介
      • 1.1 左移
      • 1.2 右移
    • 2 为什么两者会有不同呢?
      • 2.1 对于左移操作
      • 2.2 对于右移操作
      • 2.3 这样就能说明SHL和SAL是相同的吗?
        • 2.3.1 对于左移操作:
        • 2.3.2 对于右移操作
    • 3 其他

1 移位指令简介

1.1 左移

SAL		OPD, OPS               ; 算术左移,操作数左移,最低位补0,最高位进CF
SHL		OPD, OPS               ; 逻辑左移,操作数左移,最低位补0,最高位进CF

1.2 右移

SAR		OPD, OPS			   ; 算术右移,操作数右移,最高位不变,最低位进CF
SHR		OPD, OPS			   ; 逻辑右移,操作数右移,最高位补0,最低位进CF

我们会发现,左移指令 SALSHL是进行同样的操作
而右移指令 SARSHR 进行的是不同的操作

2 为什么两者会有不同呢?

先来看一段C语言代码:

#include <stdio.h>
int main(void)
{char n = 64;unsigned char m = 64;n = n << 1;m = m << 1;printf("n = %d\n", n);printf("m = %d", m);return 0;
}

运行结果:

n = -128
m = 128

我们知道C语言中移位操作常用于快速乘除(左移为乘,右移为除)
但是64为什么左移1(*2)后变成了一个负数呢?
十进制数64的二进制码为01000000,当它左移后变成10000000
n为一个有符号数,所以10000000就是 -128
m为一个无符号数,所以10000000就是128

2.1 对于左移操作

可以发现,左移操作相当于乘法操作,它是会让操作数变大的,也就是说,它随时存在着溢出的风险

若左移操作保留符号位的话,那么左移会出现越来越小的情况,但是你的本意是让这个数变大这里写图片描述

最后却发现左移后的数变小了,为了规避这种溢出带来的问题,统一了左移操作,也就是说,在左移操作中,寄存器只负责储存这个数(不管是否合乎人意,它只要是个数就行),若没有溢出的时候,则原样存储。所以说左移操作是会改变符号位的(也就是上述C语言的例子)。

2.2 对于右移操作

我们知道右移操作的算术操作是除法,那么在计算机中是肯定让这个数变小的,所以不存在溢出的风险,那么设计者就把是否保留符号位的权力交给了程序编写人员,所以 SARSHR 是两个不同的操作

2.3 这样就能说明SHL和SAL是相同的吗?

2.3.1 对于左移操作:

这里写图片描述

这里写图片描述

可以明显发现,两者对应操作的机器码是完全相同的,由此可以断定, SHLSAL是不同名的同种操作,下面再来看右移操作。

2.3.2 对于右移操作

这里写图片描述

这里写图片描述

可以发现他们对应的机器码是不同的,所以 SARSHR是两个不同的操作

3 其他

关于这两者,维基百科提到:

Logical shifts are best used with unsigned numbers
逻辑移位最好用于无符号数

In an arithmetic shift, the spaces are filled in such a way to preserve the sign of the number being slid. For this reason, arithmetic shifts are better suited for signed numbers in two’s complement format
在算术移位中,移位空间被补0或者保留高位(即符号位)的方式处理,因此,算术移位操作更适用于两个有符号数的补码操作


参考:
x86 Assembly - wikibooks
SAL/SAR/SHL/SHR - 移位操作码表


这篇关于为什么SHL和SAL相同的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/781104

相关文章

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

如何根据相同分隔符提取间隔数据?

最近遇到很多提问怎么提取字符的,而这些问题都有一个相同的特征,就是要提取的内容与内容之间,都有着相同的分隔符。当然,这种问题直接用“数据” →  “分列”功能就可以一步到位实现的,但有人喜欢折腾,而更多的人又非得指定函数公式的方法,或者更多的是要保持数据的同步性。   下面,我们就来讲讲用函数公式应该怎么实现这个提取,首先来个数据和要求,如下图,将 - 号间隔的内容依次提取到右边单元格内:

eclipse中相同变量显示变色设置

java文件的设置"Window"-"preferences"-"Java"-"Editor"-"Mark Occurrences"复选框勾选 js文件的设  置"Window"-"preferences"-"web"-"javascript"-"Mark Occurrences"复选框勾选 。

MyBatis学习——解决字段名与实体类属性名不相同的冲突

转载地址:http://www.cnblogs.com/xdp-gacl/p/4264425.html

学习整理使用jquery实现获取相同name被选中的多选框值的方法

学习整理使用jquery实现获取相同name被选中的多选框值的方法 <html><head><meta charset="gbk"><!-- 引入JQuery --><script src="https://www.qipa250.com/jquery/dist/jquery.min.js" type="text/javascript"></script></head><body>

Avoided redundant navigation to current location: 路由相同报错

vue-router有一个内置保护机制,它会阻止不必要的重复导航,以提高性能并避免不必要的计算。 具体来说,错误信息中的就是试图访问的路径时,应用程序已经在当前这个路径上。因此,vue-router检测到了这个重复的导航请求,就发出了警告。 通常情况下,这种警告并不需要特别处理,因为这只是一个优化措施,防止不必要的导航。但是如果你频繁遇到这种情况,可能需要检查触发导航的部分代码逻辑是否有必要进

JS实现将两个相同的json对象合并成为一个新对象(对象中包含list或者其他对象)source===target(不破坏target的非空值)

重点申明一下, 这个方法 只限于两个完全一样的对象 ,不一样的对象请使用 下面的进行合并,   <script>let form = {name: 'liming', sex: '男'};let obj = {class: '一班', age: 15};console.log('before', form);Object.assign(form, obj); //该方法可以完成console.

代理服务器介绍,正向代理(校园网,vpn,http隧道技术),反向代理(公司服务器,frp服务),NAT和代理服务器的相同/不同点

目录 代理服务器 介绍 类型  正向代理 引入 介绍  vpn http隧道技术 反向代理 引入 隧道技术 介绍 frp服务 NAT和代理服务器 相同点 不同点 NAT 代理服务器 代理服务器 介绍 一种中间服务器,充当客户端(如个人计算机或移动设备)与目标服务器(如网站服务器)之间的中介 它接受客户端的请求,然后将这些请求转发给目标服务器,再把

EasyExcel 文件导出 - 合并某些列值相同的行

文章目录 EasyExcel 文件导出 - 合并某些列值相同的行最终效果实现思路创建单元格合并的策略类使用 EasyExcel 文件导出 - 合并某些列值相同的行 在数据处理与文件导出的过程中,我们常常会遇到各种特定的需求。今天,我们就来探讨一下使用 EasyExcel 进行文件导出时,如何合并某些列值相同的行,以实现更加高效和整洁的数据呈现。 最终效果 下面对2、3、4列

element table 表格 span-method 某一列进行相同合并 支持树结构表格

须知 这是 vue2 版本,不过理论上 vue3 也能参考使用 可以直接打开 codepen 查看代码 效果图 代码 打不开 codepen 或者codepen 失效,查看下面代码参考 <script src="//unpkg.com/vue@2/dist/vue.js"></script><script src="//unpkg.com/element-ui@2.15.14/l