我已使用GNU汇编程序的.size
指令设置了汇编中符号的大小,如何在C中访问此大小?
void my_func(void){}
asm(
"_my_stub:\n\t"
"call my_func\n\t"
".size _my_stub, .-_my_stub"
);
extern char* _my_stub;
int main(){
/* print size of _my_stub here */
}
这里是相关的objdump
0000000000000007 <_my_stub>:
_my_stub():
7: e8 00 00 00 00 callq c <main>
这是readelf的相关部分
Symbol table '.symtab' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
5: 0000000000000007 5 NOTYPE LOCAL DEFAULT 1 _my_stub
我从objdump和symbol表中看到_my_stub的大小为5。如何在C中获得此值?
答案 0 :(得分:2)
我不知道从gas中访问size属性的方法。或者,将.size
替换为
hhh:
.long .-_my_stub # 32-bit integer constant, regardless of the size of a C long
和
extern const uint32_t gfoo asm("hhh");
// asm("asm_name") sidesteps the _name vs. name issue across OSes
我在这里无法尝试,但我希望您应该能够printf("%ld\n", gfoo);
。我尝试使用.equ
,所以这将是一个常量,而不是为其分配内存,但是我从来没有使其正常工作。
这确实就.size
属性的用途提出了疑问。如果您看不懂为什么还要设置它?我不是专家,但是我有一个理论:
根据docs,对于COFF输出,.size
必须在.def/.endef
之内。查看.def,我们发现它用于开始为符号名称定义调试信息。
尽管ELF没有相同的嵌套要求,但似乎也可以认为调试是有目的的。如果仅打算将其用于调试器,则它(kinda)表示没有办法从汇编器中访问它。
答案 1 :(得分:1)
我猜您只是想获取代码段或数据段的子集的大小。这是您可以参考的组装示例(GAS&AT样式):
target_start:
// Put your code segment or data segment here
// ...
target_end = .
// Use .global to export the label
.global target_size
target_size = target_end - target_start
在C / C ++源文件中,您可以使用target_size
的标签extern long target_size
。
注意:此示例尚未经过测试。