免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: x5miao
打印 上一主题 下一主题

又发现一个C和C++的小不同 [复制链接]

论坛徽章:
0
61 [报告]
发表于 2011-10-21 00:40 |只看该作者
我继续抓辫子:
http://blog.chinaunix.net/space. ... blog&id=2907544
     但好歹是有所得:代码中不写实参、形参,省去了传递参数的开销。

-------------------------------------------------------------------------

改进三到改进四,

将函数参数,改为全局变量(抱歉我不习惯说外部变量),
认为是“有所得”。

但是你晓不晓得,在一些系统上,
用全局变量的开销,比这里传参数的开销更大。
不但不是“有所得”,还是“有所失”。

比如,ARM上,它这里传参数,只要放寄存器R0, R1..就行了,基本无开销。
拿全局变量,需要先抓“地址”的偏移放到寄存器,
然后从地址的偏移取得全局变量的地址,
然后才能用全局变量。

抱歉我想用丰富的经验打败你。。。

论坛徽章:
5
技术图书徽章
日期:2013-11-07 13:21:58技术图书徽章
日期:2013-12-07 10:34:46技术图书徽章
日期:2014-04-23 08:50:31双鱼座
日期:2014-09-16 09:12:34亥猪
日期:2015-01-23 13:37:49
62 [报告]
发表于 2011-10-21 00:41 |只看该作者
大神们都睡了吧。

论坛徽章:
0
63 [报告]
发表于 2011-10-21 00:44 |只看该作者
让我想到了清茶的严世蕃之死。
nketc 发表于 2011-10-21 00:35



    谩骂改变不了现状。
除了这三条,我其他关于他的帖子,大多是拿程序说话,不像某些人。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
64 [报告]
发表于 2011-10-21 01:00 |只看该作者
回复 61# AD8018

>> 比如,ARM上,它这里传参数,只要放寄存器R0, R1..就行了,基本无开销。
>> 拿全局变量,需要先抓“地址”的偏移放到寄存器,
>> 然后从地址的偏移取得全局变量的地址,
>> 然后才能用全局变量。

这里的"地址",是变量访问的一系列指令的地址?
arm? 又是啥os呢? executable必须是位置无关的?

论坛徽章:
0
65 [报告]
发表于 2011-10-21 01:37 |只看该作者
arm? 又是啥os呢? executable必须是位置无关的?
OwnWaterloo 发表于 2011-10-21 01:00



    指的是ARM的芯片,os没关系,executable可以位置相关。


他的文中,“改进四”中的全局变量:
int array[10];

函数要拿到这个array中拿值, 通常需要
   LDR R0, [PC, 相对PC的偏移]
   LDR R1, [R0, array中的偏移]

编译程序需要在相对PC的偏移处,预先填一个值,这个值为array的地址。
(相对PC的偏移,这个编译时编译进指令里,不需要先抓“地址”的偏移放到寄存器,这点我前面多写了,抱歉)

---------------------------------------------
他的文中,“改进三”中的用局部变量:
int main()
{
  float array[10];
  ...
  find_max( array , 10 );
  find_min( array , 10 );
  find_ave( array , 10 );
  ...
}
array只是某个时刻的栈指针SP的值,
先 MOV R0, SP
调用约定,传递前几个参数,直接用R0,R1...,
于是这是后传参数,直接拿R0,零开销。


相对来说,“改进四”中,每次到find_**函数里,要多执行一句读内存,
      LDR R0, [PC, 相对PC的偏移]
所以不用全局变量,还是划算一点。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
66 [报告]
发表于 2011-10-21 01:58 |只看该作者
回复 65# AD8018

>>   指的是ARM的芯片,os没关系,executable可以位置相关。

我觉得是否位置无关是os相关的吧?
比如同样是 i386, Windows就不支持位置无关……
以前玩wince(课程需要……)时不懂这个……  没研究过wince+arm是否是位置无关的……


>>   LDR R0, [PC, 相对PC的偏移]
>>   LDR R1, [R0, array中的偏移]
>>   编译程序需要在相对PC的偏移处,预先填一个值,这个值为array的地址。

这两处说法有矛盾? 代码是准确的?
编译器 LDR R0, [PC, stub]
链接器 LRD R0, [PC, offset]  该指令地址+offset=array地址
这样?

这就是位置无关代码吧?
不过,既然cpu可以相对PC获取数据,没有缺乏这种指令的cpu上的效率损失,直接位置无关可能更好……

论坛徽章:
0
67 [报告]
发表于 2011-10-21 02:34 |只看该作者
位置无关这个概念有待考证 ----

代码没有错,从反汇编抄过来的。
这里,LDR R0,[PC, offset]
取得一个“固定”的变量地址。
变量地址写死在程序里,我认为是位置相关。

如果位置无关,应该R9由加载器存放数据的基础地址,
LDR R0,[PC, offset] 取出数据相对于R9的偏移。
在结合R9+偏移,得到数据的实际地址。更麻烦一点。

论坛徽章:
0
68 [报告]
发表于 2011-10-21 02:38 |只看该作者
65楼提到LDR,
其代码是位置无关的,
数据是位置相关的。
executable应该包括代码+数据,所以还是位置相关的。

有点绕了。。。

论坛徽章:
0
69 [报告]
发表于 2011-10-21 02:42 |只看该作者
事实上,俺最近玩的那颗ARM, 如果不考虑数据,
看最终生成的代码,全是位置无关的(在禁止armcc位置无关的选项时),
这点真令人迷惑。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
70 [报告]
发表于 2011-10-21 02:55 |只看该作者
回复 67# AD8018

某executable/共享库中,获取数据的指令与数据之间的偏移是固定的。
只要指令的操作数是偏移而非地址,那这个executable/共享库无论加载在什么位置,该指令都不需要更多的修改。


比如 i386, call (0xe8 ) 的操作数是相对该指令的偏移。
该指令与目标之间的偏移也是固定的。
指令无论加载在什么位置都不需要更多修改。


而获取数据
mov eax, 0x123456
mov edx, [eax]
数据(地址为0x123456)与这条指令本身必须加载一个合适的位置才能正常访问。
如果没有加载在这个理想位置, 这条指令可能就要修改为
mov eax, 0x234567
mov edx, [eax]
就不是位置无关的。


arm有相对pc获取数据的指令?
存在某个 LRD ... 被指令获取的数据的地址=该指令所在地址+该指令操作数?
这样的话访问全局数据就不会像i386那么蛋疼…… 完全接受不能……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP