程序集确定代码段的大小

时间:2011-02-02 00:25:32

标签: assembly x86

考虑到包含代码段的汇编列表的一部分,如何确定代码段的大小?

3 个答案:

答案 0 :(得分:1)

如果你想手动解决这个问题,你可以抓住Intel® 64 and IA-32 Architectures Software Developer's Manuals,并通过助记符来查看源代码段助记符,并找出预期的汇编代码大小。对于英特尔架构,您可能最终得到的答案与汇编程序给出的答案略有不同,因为大多数汇编程序中都存在一些模糊的操作码 - int $3会想到这一点。

更好(也可能更准确)的方法是组合你的代码段并检查结果部分在输出文件中的大小。

答案 1 :(得分:1)

预测这个,预装配阶段,至少对于x86 / x64程序集,遗憾的是在一般情况下是不可能的,因为指令集包含歧义。即对于相同的装配指令,存在多个可能的机器代码(具有不同的尺寸)。只有汇编器本身知道它最终会选择什么二进制操作码。

那说,当然找到一段代码的大小是正常的,也是可取的;大多数汇编程序只是通过让你在代码中区分两个标签来实现这一点,例如(GNU汇编程序,即AT& T / UN * X样式):

somefunc:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $(.Lfuncend - somefunc), %eax
    leave
    ret
.Lfuncend:

当您通过汇编程序运行并再次反汇编输出时,您会看到它将$(.Lfuncend - somefunc)位内联为汇编程序生成的常量:

$ objdump -d tst.o

tst.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 :
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   b8 0b 00 00 00          mov    $0xb,%eax
   9:   c9                      leaveq 
   a:   c3                      retq   

此函数返回自己的大小,正如您所显示的偏移/二进制操作码所示,0xb / 11是正确的。

答案 2 :(得分:0)

如果您的列表是编译器的汇编器输出,您将获得最左侧列之一中每条指令的相对起始地址,后跟指令十六进制代码和指令助记符。散布在汇编指令行之间,您将找到生成其后面的指令的源代码行(除非您有高优化 - 否则很难遵循)。

有些列表会给出相对于模块开头的地址以及相对于每个函数开头的其他地址。这只是从最后一个地址减去第一个地址并在最后一行的指令十六进制代码中添加字节数的问题。