如何从一个C程序中或内联汇编得到一个C函数的大小? [英] How to get the size of a C function from inside a C program or with inline assembly?
问题描述
假设我有一个类似的功能如下:
#猫003.cINT美孚(INT A,INT B)
{
返回A + B;
}
并编译如下:
GCC -S 003.c
将得到以下结果集:
.file003.c
。文本
.globl富
.TYPE富,@function
富:
.LFB2:
pushq%RBP
.LCFI0:
MOVQ%RSP,RBP%
.LCFI1:
MOVL%EDI,-4(RBP%)
MOVL%ESI,-8(%RBP)
MOVL -8(%RBP),EDX%
MOVL -4(RBP%),%EAX
ADDL%EDX,EAX%
离开
RET
.LFE2:
.size富。 - 富/ *函数foo的大小,怎么弄呢?* /
上面的最后一行做得到的函数的大小。哪里编译器存储的大小?我可以用得到某种方式的作用大小在我出身的C程序 C或内联汇编
解决方案
有关功能大小的信息存储在 ELF 这是你的code的未经优化的编译,而优化的版本是: 请注意从 在试图使用内联汇编,给你发挥作用的大小/ code位置的绝招是不是占编译器生成的胶水code(函数入口序言/出口尾声,直列code代,...),也不是编译器重新排序内联汇编(GCC是臭名昭著这样做),因此它不是一般相信这是一个好主意。最终,这取决于你想要做什么...... 编辑:一些更多的引用,外部以及对计算器: Suppose I have a function like below: And compile it like this: The gets the following assembly result: The last line above do get the size of the function. Where does the compiler store the size? Can I get the function's size in some way in my origin C program using C or inline asm? The information about a function size is stored in the ELF Attributes for the corresponding symbol (name). C example code how to parse this programmatically is at the bottom of the Solaris manpage for This is for an unoptimized compile of your code, while the optimized version is: Note the "Size" change from The "trick" of trying to use inline assembly to give you function sizes / code locations isn't accounting for compiler-generated glue code (function entry prologues / exit epilogues, inline code generation, ...), nor for the compiler re-ordering inline assembly (gcc is notorious to do so), hence it's not generally a great idea to trust this. In the end, it depends on what exactly you're trying to do ... Edit: A few more references, external as well as on stackoverflow:
这篇关于如何从一个C程序中或内联汇编得到一个C函数的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! gelf_getsym(3ELF)
(不libelf的Linux中存在,* BSD和MacOS,以及,你需要寻找的 st_size
的 GElf_Sym
结构域),但你也可以使用objdump的用于/ elfdump(Solaris)上/ readelf(Linux)的任务: $ objdump的-h -d --section =的.text foo3.ofoo3.o:文件格式ELF64,X86-64部分:
IDX名称大小VMA LMA文件ALGN关闭
0的.text 00000012 0000000000000000 0000000000000000 00000040 2 ** 2
内容ALLOC,LOAD,只读,code
[...]
.text段拆卸:0000000000000000<富计算值:
0:55推%RBP
1:48 89 E5 MOV%RSP,RBP%
4:89 7D FC MOV%EDI,0xfffffffffffffffc(RBP%)
7:89 75 F8 MOV%ESI,0xfffffffffffffff8(RBP%)
答:8B 45 F8 MOV 0xfffffffffffffff8(RBP%),%EAX
D:03 45 FC加入0xfffffffffffffffc(RBP%),%EAX
10:C9 leaveq
11:C3 retq $ objdump的-h -d --section =的.text foo3.ofoo3.o:文件格式ELF64,X86-64部分:
IDX名称大小VMA LMA文件ALGN关闭
0的.text 00000004 0000000000000000 0000000000000000 00000040 2 ** 4
内容ALLOC,LOAD,只读,code
[...]
.text段拆卸:0000000000000000<富计算值:
0:8D 04 37 LEA(%RDI,%RSI,1),%eax中
3:C3 retq 0×12
到 4
大小的变化?这是从 .size
汇编指令会发生什么。的sizeof(功能)
# cat 003.c
int foo(int a, int b)
{
return a+b;
}
gcc -S 003.c
.file "003.c"
.text
.globl foo
.type foo, @function
foo:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -8(%rbp), %edx
movl -4(%rbp), %eax
addl %edx, %eax
leave
ret
.LFE2:
.size foo, .-foo /* size of the function foo, how to get it?*/
gelf_getsym(3ELF)
(libelf does exist in Linux, *BSD and MacOS as well, you need to look for the st_size
field of the GElf_Sym
structure), but you also can use objdump / elfdump (Solaris) / readelf (Linux) for the task:$ objdump -h -d --section=.text foo3.o
foo3.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000012 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
[ ... ]
Disassembly of section .text:
0000000000000000 <foo>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,0xfffffffffffffffc(%rbp)
7: 89 75 f8 mov %esi,0xfffffffffffffff8(%rbp)
a: 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%eax
d: 03 45 fc add 0xfffffffffffffffc(%rbp),%eax
10: c9 leaveq
11: c3 retq
$ objdump -h -d --section=.text foo3.o
foo3.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000004 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
[ ... ]
Disassembly of section .text:
0000000000000000 <foo>:
0: 8d 04 37 lea (%rdi,%rsi,1),%eax
3: c3 retq
0x12
to 4
? That's what comes from the .size
assembler directive.
sizeof(function)