关于ppc的32位立即数加载问题
来源:互联网 发布:软件模块化设计 编辑:程序博客网 时间:2024/05/20 21:43
在ppc指令体系中,一次最多加载16位立即数。要加载32位立即数,必须分两次进行。很多资料上使用如下加载指令:
lis r0, 0x1122
addi r0, r0, 0x3344
这样做确实可以成功地把0x11223344加载到r0中。可是如果换成0x11118000呢?
lis r0, 0x1111
addi r0, r0, 0x8000
请注意, addi指令是r0 = r0 + EXTS(0x8000). EXTS(0x8000) = 0xffff8000。如此,加载到r0中的值就不是0x11118000,而是0x11108000。差之毫厘,谬以千里。
那gcc是如何实现加载32位立即数的指令的呢?
首先是加载0x11223344的指令, 这是对c代码反汇编得出的指令:
lis r0, 0x1122
ori r0, r0, 0x3344
gcc放弃了addi指令,转而使用ori指令。ori指令是r0 = r0 | (16'0 | 0x8000),加载到r0中的为0x11223344。
然后是加载0x11118000的指令,自然也是用ori指令:
lis r0, 0x1111
ori r0, r0, 0x8000
所以说,加载32位立即数时要小心,如果其第15位为1,用addi就会加载出错误的数值,还是用ori较为保险
其实,在ppc指令中,加载32位立即数并不是很常见,常见的是需要将一个数从一个32位地址中加载出来,或者将一个数保存到32位地址中。
我们来看通常的做法,假设是将地址0x11223344中的值加载到r0中:
lis r1, 0x1122
lwz r0, 0x3344(r1)
那如果是将地址0x11118000中的值加载到r0中呢?
lis r1, 0x1111
lwz r0, 0x8000(r1)
不好意思,lwz指令是指r0 = MEM[r1 + EXTS(0x8000)], 所以变成r0加载地址0x11108000处的值。
至于gcc的做法,自然是先用lis加ori指令将地址存入寄存器中,再读取内存内容。
但这样并不是说lwz/lhz/lbz等指令就没有用,它们用处很大,这些指令可以进行正负偏移2^15内的寻址。编译器在将高级代码翻译成汇编指令时,已知偏移的大小,可以酌情采用lwz/lhz/lbz等指令,而省去ori指令。除此之外,如果明确知道偏移是正的,也可以直接用lwz来组合地址,比如之前的地址0x11223344。但如果不太明确,保险起见,还是要用ori指令,不然会埋下很深的安全隐患!
转自:http://blog.csdn.net/qb_2008/article/details/7907398
- 关于ppc的32位立即数加载问题
- 关于ppc的32位立即数加载问题
- ARM8位位图--第二操作数的立即数表示
- 关于ARM立即数的理解
- 关于立即数
- ARM立即数问题
- 关于 立即数 LDR STR
- ARM 的立即数
- 关于浮点数不能进行位运算的问题
- 立即数最大有多少位?
- 关于js写入cookie立即生效的问题
- Unity3D关于Destroy不会立即销毁的问题
- 立即数的存储区
- python 关于32位64位的问题
- 关于如何生成32位/64位程序的问题
- 用广播加回调函数可以实现数据的立即加载
- 延时加载和立即加载的区别
- 延迟加载和立即加载的区别
- jqgrid不能显示数据
- Android ListView从网络获取图片及文字显示
- 数据结构之哈希表(4)
- 进入黑马day1-JunitTest测试
- Java多线程同步Synchronized深入解析
- 关于ppc的32位立即数加载问题
- JAVA经典算法40题(8)
- 中文排序要注意的问题
- java Socket简单用法
- 扩展JAAS实现类实例级授权(转)
- Quartz学习
- 深入浅出Netty之三 Server请求处理
- 创建文件夹
- 进入黑马day2-解析xml三种方法(1)jaxp解析