Phi*_*ght 3 assembly gcc gnu-assembler riscv
我有一个简单的C程序示例: -
#include <stdio.h>
int main()
{
printf("hello world!");
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我使用以下命令编译它并生成程序集: -
riscv32-unknown-elf-gcc -S hello.c -o hello.asm
Run Code Online (Sandbox Code Playgroud)
其中生成以下程序集: -
.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"
Run Code Online (Sandbox Code Playgroud)
有一个预期的call printf行,但因为在这个程序集文件中没有printf的实现,我本来希望看到它请求外部实现这样的东西......
.global printf
Run Code Online (Sandbox Code Playgroud)
但是在集会中没有这样的界限.我认为如果没有全局指令,它意味着链接器只会尝试将其解析为此单个程序集文件中的标签.我认为这是全局指令的重点,所以所有标签都是单个程序集文件的本地标签,除非使用.global导出以从其他目标文件访问或通过使用.global从另一个目标文件导入.
我在这里错过了什么?
.global将当前文件中的标签标记为具有全局范围(可供其他模块使用).也许你的意思.extern.虽然.extern可以用来说标签是外部的,但GNU汇编程序实际上忽略了该指令.从手册:
.extern在源程序中被接受 - 为了与其他汇编程序兼容 - 但它被忽略了.
as将所有未定义的符号视为外部符号.
as = GNU汇编程序.
GNU汇编程序假定它在当前文件中不知道的任何标签都是外部引用.由链接器决定是否未定义.这就是为什么你没有看到任何指令标记printf为外部.在GNU汇编程序中,它没有必要.
注意:部分混淆可能在于像NASM/YASM这样的汇编程序需要一个明确的extern声明来表示符号不在正在汇编的本地模块中.那些汇编器将返回错误,表示符号未定义.这是GNU Assembler和NASM/YASM之间的一个区别.
该.global.directive不导入标签,因为它本质上是出口.它仅将当前文件中的标签标记为全局可供其他模块使用.它不用于从其他模块导入标签.从手册:
.global使符号对ld可见.如果在部分程序中定义符号,则其值可用于与其链接的其他部分程序.否则,符号从链接到同一程序的另一个文件中获取同名符号的属性.
两种拼写('.globl'和'.global')都被接受,以便与其他汇编程序兼容.
有一个.global main指示标记main为全球.如果没有它,链接器将假定它main本质上是一个特定于模块的静态标签,不能被其他模块使用.该Ç运行时库需要访问main,因为main必须被称为控制权转交给你的条目的最后一步Ç代码.
| 归档时间: |
|
| 查看次数: |
519 次 |
| 最近记录: |