为什么我们在MIPS汇编语言中使用.globl main?

Goo*_*ing 7 assembly mips

       .text
.globl main
.ent   main
Run Code Online (Sandbox Code Playgroud)

我不知道什么.globl.ent做.有什么作用?我是否需要使用globl. main.ent main所有的时间?

Nli*_*tis 8

对你来说,.globl是一个汇编指令,它告诉汇编的main符号将是从当前文件外部访问(即,它可以从其他文件中引用),并且.ent是标志着进入一个调试器(伪)操作main.


Cir*_*四事件 5

它在 GNU GAS 汇编器上的任何其他 ISA 中都是相同的,例如在 x86_64 Linux 上:

电源

.text
.global _start
_start:
    /* exit syscall */
    mov $60, %rax
    mov exit_status, %rdi
    syscall
Run Code Online (Sandbox Code Playgroud)

退出状态.S

.data
.global exit_status
exit_status:
    .quad 42
Run Code Online (Sandbox Code Playgroud)

组装并运行:

as -o main.o main.S
as -o exit_status.o exit_status.S
ls -o main.out exit_statis.o main.o
./main.out
echo $?
Run Code Online (Sandbox Code Playgroud)

给出:

42
Run Code Online (Sandbox Code Playgroud)

但如果我们删除该行:

.global exit_status
Run Code Online (Sandbox Code Playgroud)

然后ld失败:

main.o: In function `_start':
(.text+0xb): undefined reference to `exit_status'
Run Code Online (Sandbox Code Playgroud)

exit_status因为它看不到它需要的符号。

.globl.global文档中提到的同义词:https://sourceware.org/binutils/docs/as/Global.html#Global所以我更喜欢使用拼写正确的那个;-)

我们可以通过查看ELF 目标文件中包含的信息来观察正在发生的情况。

对于正确的程序:

nm hello_world.o mystring.o
Run Code Online (Sandbox Code Playgroud)

给出:

main.o:
0000000000000000 T _start
                 U exit_status

exit_status.o:
0000000000000000 D exit_status
Run Code Online (Sandbox Code Playgroud)

对于失败的人:

exit_status.o:
0000000000000000 d exit_status
Run Code Online (Sandbox Code Playgroud)

和:

man nm
Run Code Online (Sandbox Code Playgroud)

包含:

符号类型。至少使用以下类型;其他也取决于目标文件格式。如果是小写,则该符号通常是本地的;如果大写,则该符号是全局的(外部)。然而,有一些小写符号显示为特殊的全局符号(“u”、“v”和“w”)。

"D"
"d" The symbol is in the initialized data section.

"T"
"t" The symbol is in the text (code) section.

"U" The symbol is undefined.
Run Code Online (Sandbox Code Playgroud)

在 C 级别,您可以使用关键字控制符号可见性static“static”在 C 中意味着什么?

在 Ubuntu 16.04、Binutils 2.26.1 中测试。