组装中的功能是什么? [英] What is function in assembly?
问题描述
我正在尝试研究汇编,编译器(LLVM)和提升器.
I am trying to study about assembly, compiler(LLVM) and lifter.
我可以用nasm编写汇编代码.(例如此)
I can write just assembly code by nasm.(like this)
下面是我的汇编代码.
section .data
hello_string db "Hello World!", 0x0d, 0x0a
hello_string_len equ $ - hello_string
section .text
global _start
_start:
mov eax, 4 ; eax <- 4, syscall number (print) But, never execute.
mov ebx, 1 ; ebx <- 1, syscall argument1 (stdout) But, never execute.
mov ecx, hello_string ; ecx <- exit_string, syscall argument2 (string ptr) But, never execute.
mov edx, hello_string_len ; edx <- exit_string_len, syscall argument3 (string len) But, never execute.
int 0x80; ; syscall But, never execute.
mov eax, 1 ; eax <- 1, syscall number (exit) But, never execute.
mov ebx, 0 ; ebx <- 0, syscall argument1 (return value) But, never execute.
int 0x80; syscall But, never execute.
;nasm -felf32 hello.x86.s -o hello.o
;ld -m elf_i386 hello.o -o hello.out
然后我检查二进制文件.
And I check binary file.
在这里,我找不到功能.并且我同意该呼叫和退回指令是一些指令的组合.
Here, I can't find Function. and i agree with that call and ret instructions are something combined some instructions.
$readelf -s hello.o
Symbol table '.symtab' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS hello.x86.s
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 2
4: 00000000 0 NOTYPE LOCAL DEFAULT 1 hello_string
5: 0000000e 0 NOTYPE LOCAL DEFAULT ABS hello_string_len
6: 00000000 0 NOTYPE GLOBAL DEFAULT 2 _start
但是.如果我编译C程序并通过readelf检查该二进制文件.然后我可以找到功能".
But. If i compile c program and check that binary file by readelf. then i can find "function".
PS
$readelf -s function.o | grep FUNC
3: 0000000000000000 18 FUNC GLOBAL DEFAULT 2 add
4: 0000000000000020 43 FUNC GLOBAL DEFAULT 2 main
在这里我可以看到什么是功能.
here i can see what is function.
功能不同的NOTYPE标签是什么?
what is function different NOTYPE label?
推荐答案
ELF符号元数据可以由某些汇编程序设置,例如在NASM中,使用 global main:function
将符号类型标记为FUNC.( https://nasm.us/doc/nasmdoc8.html#section-8.9.5 ).
ELF symbol metadata can be set by some assemblers, e.g. in NASM, global main:function
to mark the symbol type as FUNC. (https://nasm.us/doc/nasmdoc8.html#section-8.9.5).
等效的GAS语法(C编译器发出)是 .type main,function
.例如在 https://godbolt.org 上放置一些代码,并禁用过滤以在编译器输出中查看asm指令.
The GAS syntax equivalent (which C compilers emit) is .type main, function
. e.g. put some code on https://godbolt.org and disable filtering to see asm directives in compiler output.
但是请注意,这只是供链接器和调试器使用的元数据.CPU在执行时看不到它.这就是为什么没人为NASM示例而烦恼的原因.
But note this is just metadata for linkers and debuggers to use; the CPU doesn't see that when executing. That's why nobody bothers with it for NASM examples.
汇编语言并没有真正的功能,只是实现该概念的工具,例如跳转并将返回地址存储在某个地方= call
,间接跳转到返回地址= ret
.在x86上,返回地址被压入并弹出堆栈.
Assembly language doesn't truly have functions, just the tools to implement that concept, e.g. jump and store a return address somewhere = call
, indirect jump to a return address = ret
. On x86, return addresses are pushed and popped on the stack.
执行模型是纯粹顺序的和局部的,一次只执行一条指令(在大多数ISA上,但有些ISA是VLIW,例如一次执行3条,但在范围上仍然是局部的),每条指令仅构成一个对架构状态进行明确定义的更改.CPU本身不知道或不在乎它是否在功能中".或其他有关嵌套的内容,但返回地址预测变量堆栈乐观地认为 ret
将实际使用由相应的 call
推送的返回地址.但这是性能上的优化;如果代码做得很奇怪(例如,上下文切换),有时您会得到不匹配的调用/返回.
The model of execution is purely sequential and local, one instruction at a time (on most ISAs, but some ISAs are VLIW and execute 3 at a time for example, but still local in scope), with each instruction just making a well-defined change to the architectural state. The CPU itself doesn't know or care that it's "in a function" or anything about nesting, other than the return-address predictor stack which optimistically assumes that ret
will actually use a return address pushed by a corresponding call
. But that's a performance optimization; you do sometimes get mismatched call/ret if code is doing something weird (e.g. a context switch).
C编译器不会在函数之外放置任何指令.
A C compiler won't put any instructions outside of functions.
从技术上讲,间接调用 main
的 _start
入口点不是函数;它不能返回,必须进行 exit
系统调用,但这是用asm编写的,并且是libc的一部分.它不是由C编译器适当生成的,仅与C编译器的输出链接以创建工作程序.)请参见
Technically the _start
entry point that indirectly calls main
isn't a function; it can't return and has to make an exit
system call, but that's written in asm and is part of libc. It's not generated by the C compiler proper, only linked with the C compiler's output to make a working program.) See Linux x86 Program Start Up
or - How the heck do we get to main()? for example.
这篇关于组装中的功能是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!