文章目录
1 移位指令简介
1.1 左移
SAL OPD, OPS ; 算术左移,操作数左移,最低位补0,最高位进CF
SHL OPD, OPS ; 逻辑左移,操作数左移,最低位补0,最高位进CF
1.2 右移
SAR OPD, OPS ; 算术右移,操作数右移,最高位不变,最低位进CF
SHR OPD, OPS ; 逻辑右移,操作数右移,最高位补0,最低位进CF
我们会发现,左移指令 SAL
和SHL
是进行同样的操作
而右移指令 SAR
和SHR
进行的是不同的操作
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 对于右移操作
我们知道右移操作的算术操作是除法,那么在计算机中是肯定让这个数变小的,所以不存在溢出的风险,那么设计者就把是否保留符号位的权力交给了程序编写人员,所以 SAR
和SHR
是两个不同的操作。
2.3 这样就能说明SHL和SAL是相同的吗?
2.3.1 对于左移操作:
可以明显发现,两者对应操作的机器码是完全相同的,由此可以断定, SHL
和 SAL
是不同名的同种操作,下面再来看右移操作。
2.3.2 对于右移操作
可以发现他们对应的机器码是不同的,所以 SAR
和 SHR
是两个不同的操作。
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 – 移位操作码表
今天的文章SAL是什么意思_sal是什么缩写分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/63881.html