免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4734 | 回复: 8
打印 上一主题 下一主题

请问编译器如何生成内存地址? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-08 14:26 |只看该作者 |倒序浏览
在汇编器完成对指令的汇编操作后,如何计算某个变量或指令的内存地址?

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2007-04-08 16:08 |只看该作者
一条指令一条指令的计算下来的

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
3 [报告]
发表于 2007-04-08 16:09 |只看该作者
另外,如果是栈上变量,则通过栈指针寻址。

[ 本帖最后由 cjaizss 于 2007-4-8 16:30 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-04-08 17:09 |只看该作者
汇编器(assembler)只是生成一个需重定位的object文件。这个目标文件需经过链接器(Linker)与相应的库链接起来生成一个可执行的文件。

assembler 产生的代码是从 0 开始编址。经过 Lineker 重定位后生成的可执行映象按OS的不同而不同。

至于内存中的全局以及静态变量的编址也是需重定位的。局部变量则无需重定位

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
5 [报告]
发表于 2007-04-08 17:55 |只看该作者
原帖由 mik 于 2007-4-8 17:09 发表于 4楼  
汇编器(assembler)只是生成一个需重定位的object文件。这个目标文件需经过链接器(Linker)与相应的库链接起来生成一个可执行的文件。

assembler 产生的代码是从 0 开始编址。经过 Lineker 重定位后生成的 ...

恩,我再补充一点点——
给LZ三段代码

  1. /**1.c***/
  2. extern int d;
  3. int func(int i,int j)
  4. {
  5.         int I,J;
  6.         I=i;
  7.         J=j;
  8.         return I+J+d;
  9. }
  10. int func2(int i,int j)
  11. {
  12.         return func(i,j)+1;
  13. }

复制代码

  1. /**2.c**/
  2. int d=7;
  3. int func2(int,int);
  4. int main()
  5. {
  6.         func2(1,2);
  7.         return 0;
  8. }
复制代码

然后

  1. gcc -c 1.c
  2. gcc -c 2.c
  3. gcc 1.o  2.o
复制代码

然后反编译
objdump -D 1.o >1
objdump -D 2.o >2
objdump -D a.out >a
然后仔细比较1,2,a三个文件中的汇编码和机器码。

论坛徽章:
0
6 [报告]
发表于 2007-04-08 18:42 |只看该作者
当不用编译器就可以写代码的时候,就能彻底地明白是怎么一回事。

我最近在写一个64 位 OS 的 loader,就是无需任何编译器。直接写机器指令。用十六进制编辑软件来写。然后直接生成可启动映象。很简单。头痛的是还要写 64 位中断例程(或者说是系统调用),才能干些什么实质的事情!

很爽!很自由。有成功感。其中,变量的位置就是任你放哪。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2007-04-08 20:38 |只看该作者
原帖由 mik 于 2007-4-8 18:42 发表于 6楼  
当不用编译器就可以写代码的时候,就能彻底地明白是怎么一回事。

我最近在写一个64 位 OS 的 loader,就是无需任何编译器。直接写机器指令。用十六进制编辑软件来写。然后直接生成可启动映象。很简单。头痛的 ...

用汇编写也一样的啊,两者一一对应啊
主要是直接用机器语言写更容易出错

论坛徽章:
0
8 [报告]
发表于 2007-04-09 10:42 |只看该作者
原帖由 mik 于 2007-4-8 18:42 发表于 6楼  
当不用编译器就可以写代码的时候,就能彻底地明白是怎么一回事。

我最近在写一个64 位 OS 的 loader,就是无需任何编译器。直接写机器指令。用十六进制编辑软件来写。然后直接生成可启动映象。很简单。头痛的 ...


净让人羡慕。
不禁让我想起那个用电话上的0和1编写出98的高人来,看来是有现实生活中的原型的。

论坛徽章:
0
9 [报告]
发表于 2007-04-16 12:12 |只看该作者
汇编生成的,是一些浮动模块和一张符号表。链接器按照这张符号表,把这些模块装配成一个整体。在运行时,系统的装载器做重定位,才真正确定了地址。这个地址还是虚拟地址。系统的存储管理子系统为其分配真正的物理地址。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP