cdsfiui 发表于 2016-09-24 15:57

我的汇编程序,链接-lc就会无法运行?

我在32位的ubuntu1604上面做了个很小的实验:
$ cat g.s
.section .text
.globl _start
_start:
movl $1,%eax
int $0x80只是一个exit调用而已,别的什么也没有。
$ as g.s -o g.o && ld g.o -o g
$ g没有问题。但是如果我试图链接-lc就会有问题。
$ as g.s -o g.o && ld g.o -o g -lc
$ gbash: ./g: 没有那个文件或目录

我本来想尝试一下在汇编代码里面去调用call printf/call exit这样的c函数的。
但是发现即使什么也不掉用,光是链接的话,都会导致生成的2进制程序无法运行。

这看起来非常奇怪,我ldd看了一下,都能找到的:
$ ldd g
    linux-gate.so.1 =>(0xb7756000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7582000)
    /usr/lib/libc.so.1 => /lib/ld-linux.so.2 (0x8003e000)为什么运行就不行了? ./g运行也是不行,同样的错。
我最后尝试了一下带着调试信息来编译,并且用gdb来运行,如下所示:
$ as -g g.s -o g.o && ld g.o -o g -lc
$ gdb g
...
(gdb) list
1    .section .text
2    .globl _start
3    _start:
4    movl $1,%eax
5    int $0x80
(gdb) b 3
Breakpoint 1 at 0x80480ff: file g.s, line 3.
(gdb) r
Starting program: /home/x/cpp/g
/bin/bash: /home/x/cpp/g: 没有那个文件或目录
During startup program exited with code 127.看起来,gdb能够抓到这个错误,也就是During startup program existed。刚启动就退出了,shell还没有来得及执行它,所以shell说找不到这个程序,对吧。
但是原因是什么呢? 大侠给点解释吧,我觉得从gas汇编的程序去链接c运行时库应该是个很普通的场景啊,这个错误如何更正?

MMMIX 发表于 2016-09-24 16:33

本帖最后由 MMMIX 于 2016-09-24 16:42 编辑

回复 1# cdsfiui

$ as g.s -o g.o && ld g.o -o g -lc
$ g
bash: ./g: 没有那个文件或目录

这个非常有迷惑性的错误是 kernel 报出来的,找不到正确的 loader (i.e. dynamic linker).



这看起来非常奇怪,我ldd看了一下,都能找到的:
$ ldd g
    linux-gate.so.1 =>(0xb7756000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7582000)
    /usr/lib/libc.so.1 => /lib/ld-linux.so.2 (0x8003e000)


loader 呢? 用 readelf -Wl g 看看具体的 loader 是啥,是否正确。
总之还是一句话,多看看 gcc 的例子,不要自己瞎试。

cdsfiui 发表于 2016-09-25 11:46

MMMIX 发表于 2016-09-24 16:33
回复 1# cdsfiui





$ readelf -Wl g

Elf 文件类型为 EXEC (可执行文件)
入口点 0x80480ff
共有 5 个程序头,开始于偏移量 52

程序头:
Type         Offset   VirtAddr   PhysAddr   FileSiz MemSizFlg Align
PHDR         0x000034 0x08048034 0x08048034 0x000a0 0x000a0 R E 0x4
INTERP         0x0000d4 0x080480d4 0x080480d4 0x00013 0x00013 R   0x1
      
LOAD         0x000000 0x08048000 0x08048000 0x00108 0x00108 R E 0x1000
LOAD         0x000108 0x08049108 0x08049108 0x00068 0x00068 RW0x1000
DYNAMIC      0x000108 0x08049108 0x08049108 0x00068 0x00068 RW0x4

Section to Segment mapping:
段节...
   00   
   01   .interp
   02   .interp .hash .dynsym .dynstr .text
   03   .dynamic
   04   .dynamic


MMMIX 发表于 2016-09-25 14:50

回复 3# cdsfiui

loader 明显不对嘛,你看看正常的可执行文件 loader 是啥。另外,也可以看看 gcc 在链接的时候是怎么指定 loader 的。

cdsfiui 发表于 2016-09-26 11:14

MMMIX 发表于 2016-09-25 14:50
回复 3# cdsfiui

loader 明显不对嘛,你看看正常的可执行文件 loader 是啥。另外,也可以看看 gcc 在链 ...

这个loader明显不对是怎么看出来的? 我看这个loader和普通c文件被gcc编译之后ldd看到的loader是同一个啊

MMMIX 发表于 2016-09-26 15:04

本帖最后由 MMMIX 于 2016-09-26 15:05 编辑

回复 5# cdsfiui



这个loader明显不对是怎么看出来的?

$ ldd /bin/ls
         ...
      /lib64/ld-linux-x86-64.so.2 (0x00005599b730f000)
      ...

$ readelf -Wl /bin/ls
...
INTERP         0x000238 0x0000000000000238 0x0000000000000238 0x00001c 0x00001c R   0x1
      
...

正常情况下的 loader 。
页: [1]
查看完整版本: 我的汇编程序,链接-lc就会无法运行?