为什么操作int 类型的指令要快于操作short 的,却可能慢于操作char 的

唔,写这篇博客的原因是贴吧里碰到了小破太激动了,看到小破说指令的效率回了几句。。。。

趁着想着这件事的时候写下来吧,因为这个确实不好在QQ 里说明白,改天再写的话我这破脑子一定会忘了……


1. 为什么对int 变量的操作比操作short 变量的指令快

如果你看过操作系统引导部分的资料的话,你就明白在描述符中D/B 位决定了CPU 指令的默认地址,如果置位则表示是32 位地址,复位就是8/16 位地址(我没看过64 位保护模式的资料原谅我吧)。一般来说我们的机器都是32 位的,所以32 位的机器只能操作32 位的地址。
但是这里有一个0x66 指令前缀(Prefixes ),这个前缀的作用就是切换默认操作数大小,所以当你在32 位系统上去操作一个8/16 位的变量的时候,那么就会在机器码前面增加一个0x66 前缀,这是就会多话费一个CPU 周期去执行。

但是对于char 呢?操作int 的指令比操作short 的快,并不代表操作int 的指令都要比操作长度小于sizeof (int) 变量的指令要快。

事实上操作int 的语句确实比操作short 的快,但是至少和操作char 的一样快。


2. 为什么操作int 类型的指令要快于操作short 的,却可能慢于操作char 的

程序:

short aShort = 0;
int aInt = 0;
objdump 之后:
4004b4: 66 c7 45 fe 00 00 movw $0x0,-0x2(%rbp)
4004ba: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp) 
程序:
char aChar = 0;
int aInt = 0;
objdump 之后:
4004b4: c6 45 ff 00 movb $0x0,-0x1(%rbp)
4004b8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp) 
对于short 类型的确实加了x66 前缀了,但是char 类型的mov 中就没加,差了下指令表:
MOVmi 1100011w oo000www disp data 
蛋疼的是objdump 输出的att 格式的汇编,不顺眼写成MOVim 也行。
对于char 的操作,汇编器选择了直接复位w 位,直接换成对字节的操作了。
short 则不是,w 是置位的,对字操作,但是因为D/B 的关系,默认是操作双字,所以才加的x66 前缀改变了默认操作地址大小为字。

所以操作int 的语句确实比操作short 的快,但是至少和操作char 的一样快。


3. 对于0x66 Prefix 如何起作用的的进一步说明

对于0x66 Prefix,可以用一条x86_64 架构上的机器码手动反汇编过程来说明:

4004b4: 66 c7 45 fe 00 00 
4004b4: 66 c7 45 fe 00 00
66:Operand-Size Override prefix,用来更改默认Operand-Size(Descriptor 上的D/B 位)。
c7:MOVmi 1100011w,其中w 置位。查找指令表1100011,发现只有一条MOVmi 指令符合。所以0xc7 是一条mov 指令,将大小为双字的立即数送到一块内存。但是对于CPU 而言这条指令有Group 属性,需要配合ModR/M.reg 来配合定位(也就是0xc7 并不是完整的opcode)。
45:0b0100_0101,ModR/M 位,为了直观写作0b01_000_101
ModR/M.mod = 0b01:寻址模式base+disp8。
ModR/M.reg = 0b000:MOVmi 中对应的ModR/M.reg 位是oo000www,由ModR/M.reg 和0xc7 共同确定了指令MOVmi。
ModR/M.r/m = 0b101:结合ModR/M.mod = 0b01,查表可得rbp+disp8
fedisp8,8 位偏移量,-2
00 00:imm8,8 位立即数( 实际上是16 位):0。之所以实际上是16 位,原因是原本立即数是8 位的,但是因为D/B 位被置位,立即数大小变为32,这里又加了0x66 前缀,所以立即数大小变为16 位。
结合0x66 前缀,操作数由双字变为字,对应指令就是

movw $0x0000, -0x2(%rbp)

这就是0x66 Prefix 起作用的一个例子,事实上手动反汇编的结果和objdump 之后得到的结果完全一致。



就是这样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值