【发布时间】:2018-05-13 18:56:03
【问题描述】:
我有一个简单的 C 程序示例:-
#include <stdio.h>
int main()
{
printf("hello world!");
return 1;
}
我使用以下命令编译它并生成程序集:-
riscv32-unknown-elf-gcc -S hello.c -o hello.asm
生成以下程序集:-
.file "hello.c"
.option nopic
.section .rodata
.align 2
.LC0:
.string "hello world!"
.text
.align 2
.globl main
.type main, @function
main:
addi sp,sp,-16
sw ra,12(sp)
sw s0,8(sp)
addi s0,sp,16
lui a5,%hi(.LC0)
addi a0,a5,%lo(.LC0)
call printf
li a5,1
mv a0,a5
lw ra,12(sp)
lw s0,8(sp)
addi sp,sp,16
jr ra
.size main, .-main
.ident "GCC: (GNU) 7.2.0"
有一个预期的call printf 行,但由于此程序集文件中没有 printf 的实现,我希望看到它请求一个具有类似这样的外部实现...
.global printf
但是程序集中没有这样的行。我认为如果没有 global 指令,这意味着链接器只会尝试将其解析为单个程序集文件中的标签。我认为这就是 global 指令的全部意义,因此所有标签都是单个程序集文件的本地标签,除非使用 .global 导出以从其他目标文件访问,或者也使用 .global 从另一个目标文件导入。
我在这里错过了什么?
【问题讨论】:
-
链接器在 C 运行时自动链接。由于这个原因,我认为不需要全局指令。
-
.global会将当前文件中的标签标记为具有全局范围(可用于其他模块)。也许你的意思是.extern。尽管.extern可以用来表示标签是外部的,但该指令实际上被忽略了。 GNU 汇编器假定它在当前文件中不知道的任何标签都被自动假定为外部标签(由链接器决定它是否未定义)。这就是为什么您看不到任何将printf标记为外部的指令的原因——这没有必要。 -
所以你说你需要使用 .global 从模块导出但不需要使用 .global 导入?猜猜这解释了为什么它仍然使用 .global 作为 main。
-
是的,就是这样。
标签: gcc assembly gnu-assembler riscv