LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1427|回复: 23

汇编的问题

[复制链接]
发表于 2005-5-16 13:38:55 | 显示全部楼层 |阅读模式
c程序转化为汇编后该怎么汇编呢?
我的作法如下:
这是我的c程序

  1. /* t.c */
  2. #include <stdio.h>

  3. int f(int a)
  4. {
  5.         return a++;
  6. }

  7. int main()
  8. {
  9.         int v = 1;
  10.         f(v);
  11.         return 0;
  12. }
复制代码

# gcc -S -O3  t.c后结果如下
  1.         .file   "t.c"
  2.         .text
  3.         .p2align 4,,15
  4. .globl f
  5.         .type   f, @function
  6. f:
  7.         pushl   %ebp
  8.         movl    %esp, %ebp
  9.         movl    8(%ebp), %eax
  10.         popl    %ebp
  11.         ret
  12.         .size   f, .-f
  13.         .p2align 4,,15
  14. .globl main
  15.         .type   main, @function
  16. main:
  17.         pushl   %ebp
  18.         xorl    %eax, %eax
  19.         movl    %esp, %ebp
  20.         subl    $8, %esp
  21.         andl    $-16, %esp
  22.         subl    $16, %esp
  23.         leave
  24.         ret
  25.         .size   main, .-main
  26.         .ident  "GCC: (GNU) 4.0.0 (Gentoo Linux 4.0.0)"
  27.         .section        .note.GNU-stack,"",@progbits
复制代码

链接的时候出了点问题
  1. [leo@leo test]$ as t.s -o t.o
  2. [leo@leo test]$ ld -dynamic-linker /lib/ld-linux.so.2 -o a.out t.o
  3. ld: warning: cannot find entry symbol _start; defaulting to 00000000080480c0
复制代码

我于是在.text后加了两句
  1. .globl _start
  2. _start:
复制代码

这样链接就没有warning了,但运行程序时会出现Segmentation fault,不知道什么原因

btw 用gdb调试汇编程序可以查看寄存器的值么?
发表于 2005-5-16 15:15:40 | 显示全部楼层

  1. ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -lc t.o /usr/lib/crtn.o
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-16 19:09:38 | 显示全部楼层
感谢kj斑竹的解答,我晚上到自己的机器上去试一下

有个疑问就是:我没有用到c的库函数啊,干吗要连接c库呢?
还有/usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o都是些什么东西啊?
回复 支持 反对

使用道具 举报

发表于 2005-5-17 09:52:12 | 显示全部楼层
不需要采用c库。
ld 没采用-e ADDRESS选项,ld -e main 应该就可以了。
-e选项的含义是,指定程序进入点的地址(--entry)
回复 支持 反对

使用道具 举报

发表于 2005-5-17 10:01:28 | 显示全部楼层
-dynamic-linker /lib/ld-linux.so.2
而且这个也可以去掉。
我的操作:
debian:/home/apple# gcc -S t.c -o t.s
debian:/home/apple# as t.s -o t.o
debian:/home/apple# ld -e main t.o -o t
没有任何问题
回复 支持 反对

使用道具 举报

发表于 2005-5-17 10:02:47 | 显示全部楼层
楼主是不是用mingw在win32平台编译的?我用mingw试了一下,产生了楼主说的问题。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-17 12:38:04 | 显示全部楼层
不是啊,我没有win

用kj斑竹的方法确实可以成功了

我的源程序确实有点混乱,由于习惯问题,想都没想就把stdio.h给include了,其实是不用的
然后我就用了-dynamic-linker /lib/ld-linux.so.2,其实程序并没有链接动态库,正如realtang兄所说,这个参数也是没有必要的,是我犯糊涂了。或许斑竹受我的误导才链接了c库的吧:)

还有,我按realtang兄的方法做还是不能成功,如下:
  1. [leo@leo test]$ gcc -S t.c -o t.s
  2. [leo@leo test]$ as t.s -o t.o
  3. [leo@leo test]$ ld -e main t.o -o t
  4. [leo@leo test]$ ./t
  5. Segmentation fault
复制代码

warning倒是没有,就是仍有段错误。
我的系统:gentoo 2005.0 gcc-4.0(汇编代码中都有的)

奇怪的是,如果不完全按照kj斑竹的作法,即
把-dynamic-linker /lib/ld-linux.so.2去掉,虽然可以生成可执行文件,但还是会有问题,搞不懂了
  1. [leo@leo test]$ ld  /usr/lib/crt1.o /usr/lib/crti.o -lc t.o /usr/lib/crtn.o
  2. [leo@leo test]$ ./a.out
  3. bash: ./a.out: No such file or directory
  4. [leo@leo test]$ file a.out
  5. a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.6, dynamically linked (uses shared libs), not stripped
复制代码

回复 支持 反对

使用道具 举报

发表于 2005-5-17 14:27:57 | 显示全部楼层
静态连接是可以的:
ld --static /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o -lc test.o
回复 支持 反对

使用道具 举报

发表于 2005-5-17 14:41:32 | 显示全部楼层
crt* 应该是 C Runtime 的意思吧.

想想如果没有c库的支持,程序怎么退出(即进程如何终止)?
main函数会return到什么地方?
将会return到一个不该到的地方,那就会Segmentation fault了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-17 17:00:56 | 显示全部楼层
Post by rickxbx
crt* 应该是 C Runtime 的意思吧.

想想如果没有c库的支持,程序怎么退出(即进程如何终止)?
main函数会return到什么地方?
将会return到一个不该到的地方,那就会Segmentation fault了

恩,好像有点明白了
有空再多想想

我用gdb跟踪过,确实是可以运行的,就是return后出错了,可能正如rickxbx兄所说不知return到什么地方去了吧

谢谢大家,我再查查资料   
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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