曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4572|回复: 0
打印 上一主题 下一主题

移位运算

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2010-2-11 21:18:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
乘法和除法指令是处理器上最耗时的两种指令。但是像基于 2 的乘方的乘法和除法可以用移位运算来迅速完成。

1、移位乘法
向左移动 1 位相当于乘以 2,这里有两条指令,SAL(算术左移位) 和 SHL (逻辑左移位)。这两个指令执行相同的操作,它们有 3  种不同的格式:
sal destination
sal %cl, destination
sal shifter, destination
第 1 种格式把 destination 的值向左移 1 位,等同于乘以 2。
第 2 种格式把 destination 的值向左移动 CL 寄存器里指定的位数。
第 3 种格式把 destination 的值向左移动 shifter 值指定的位数。

在具体的指令应用中,指令助记符的结尾要附加上一个字符,用于指出目标值的长度。

可以对带符号和无符号整数执行向左移指令。移位造成的空位用零填充,移出的数位放在位标志中,每次移动这个位标志里的值都会被移动出来的新值挤出。

测试程序
# sal.s - An example of the SAL instruction
.section .data

value1:
    .int 25

.section .text
.global _start
_start:
    nop
    movl $10, %ebx
    sall %ebx
    movb $2, %cl
    sall %cl, %ebx
    sall $2, %ebx
    sall value1
    sall $2, value1
    movl $1, %eax
    movl $0, %ebx
    int $0x80
在 GDB 里可以看到程序执行移位指令后各自的值:
(gdb) x/d &value1
0x804909c <value1>:    200
(gdb) info reg
eax            0x0    0
ecx            0x2    2
edx            0x0    0
ebx            0x140    320
如果在源程序中把 .section .text 不小心写错了,如写成 .section .dext ,那么在调试时会出现下面的错误提示:
No symbol table is loaded.  Use the "file" command.

2、移位除法
在移位除法里,当把整数向右移时,必须注意整数的符号。

对于无符号整数,向右移位产生的空位可以被填充为 0 ,而且不会有任何问题。不幸的是,对于带符号整数,使用 0 填充高位部分会对负数产生有害影响。为了解决这个问题,就有了两个右移指令。SHR 指令清空移位造成的空位,所以它只能用于对无符号整数进行的移位操作。SAR 指令根据整数的符号位,要么清空,要么设置移位造成的空位。对于负数,空位被设置为 1,而对于正数,则被清空为 0 。

和左移指令一样,右移指令移出的元素也会被移动到进位标志中去,如果再有移位,原先在进位标志里的元素会被挤掉。

3、循环移位
循环移位指令执行的功能和移位指令一样,只不过溢出位被存放回值的另一端,而不是被丢弃。下表是各种循环移位指令:
指令
描述
ROL
向左循环移位
ROR
向右循环移位
RCL
向左循环移位,并且包含进位标志
RCR
向右循环移位,并且包含进位标志
上表中最后 2 条指令使用进位标志作为附加位的位置来支持 9 位移位。循环移位指令的格式和移位指令相同,也有 3 种格式:
      单一操作数:按照指定的方向把它移动 1 位。
      2个操作数:指定循环次数的 %cl 寄存器和目标操作数。
      2个操作书:指定循环次数的立即数和目标操作数。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-14 14:11 , Processed in 0.063776 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表