考虑仅具有简单的32位x86汇编语句的文件:

call 0xc1066580


如果使用nasm -f elf汇编此文件,则会得到:

   0:   e8 7c 65 06 c1          call   0xc1066581


如果我使用GCC并指定-Ttext = 0和-nostdlib,则会得到:

   0:   e8 7b 65 06 c1          call   c1066580


-nostdlib
    链接时,请勿使用标准的系统启动文件或库。没有启动文件,只有指定的库才传递给链接器,并且指定系统库链接的选项(例如-static-libgcc或-shared-libgcc)将被忽略。

但是-Ttext = 0到底能做什么?我用它来指定EIP在加载/执行时开始的入口地址。我在联机帮助中找不到-Ttext,当我在线搜索时发现:

“ -Ttext是“ --section-start = text”的别名,其读作为:
--section-start = sectionname = org
在给定的绝对地址下找到输出文件中的部分
由org。您可以根据需要多次使用此选项
在命令行中找到多个部分。组织必须是一个
十六进制整数;为了与其他链接器兼容,您可以
省略通常与十六进制值关联的前导0x。
注意:段名之间不应有空格,
等于符号(“ =”)和org。“

来自http://www.linuxquestions.org/questions/linux-general-1/gcc-creating-a-huge-executable-image-redhat-2-6-18-8-el5-x86_64-linux-759302/

但是,我也没有在手册页中找到--section或sectionname,当我尝试用--section-name替换-Ttext时,我得到了一个无法识别的参数(如果相关,则为GCC 4.7.2 )。

有人可以告诉我(-Ttext)的解释是正确的,还是在手册中可以找到?如果不准确,-Ttext到底能做什么?

我的另一个问题是:如何为nasm指定与-Ttext类似的参数?换句话说,我该怎么做才能使nasm产生与gcc相同的输出?

我尝试在64位和32位系统上执行相同的汇编语句(使用nasm和gcc),得到的结果相同。

最佳答案

运行ld --help给出

-Ttext ADDRESS              Set address of .text section



如果我们使用gcc -Ttext=8 -nostdlib -o test test.s汇编以下程序

.globl _start
_start:
movl test,%ebx
test:


并转储节标题(objdump -h test):

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000007  0000000000000008  0000000000000008  00200008  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE


..和代码(objdump -d test):

0000000000000008 <_start>:
   8:   8b 1c 25 0f 00 00 00    mov    0xf,%ebx


我们可以看到.text节的起始地址为8,大小为7。也就是说,该节中对符号的所有引用都已被我们指定的起始地址(8)偏移,但是没有填充(由于更改了地址,节的大小并未增加)。

通过使用ORG directive,您应该能够使用NASM完成相同的操作:“ NASM的ORG完全按照指令的指示进行操作:origin。它的唯一功能是指定一个偏移量,该偏移量将添加到该节中的所有内部地址引用中” 。

08-15 23:02