皋陶 发表于 2021-3-4 15:10:13

RiscV汇编介绍(2)-编译过程

本帖最后由 皋陶 于 2021-3-4 15:12 编辑

RiscV汇编介绍(1)-编译过程RiscV汇编介绍(2)-编译过程
elf文件全称是Executable and Linkable Format,可执行连接格式,elf文件中除了机器码以外,还有段加载地址,运行入口地址,数据段等。
elf文件格式主要有如下三种:

[*]可重定向文件:文件保存着代码和适当的数据,用来和其它的目标文件一块儿来建立一个可执行文件或者共享目标文件。
[*]可执行文件:文件保存着一个用来执行的文件。
[*]共享目标文件:即共享库。


elf文件详解:
http://www.javashuo.com/article/p-unwgtgag-z.htmlhttps://blog.csdn.net/afterlake/article/details/53648912
咱们用riscv工具链获得hello.c程序的汇编代码以下,对于rv32和rv64 gcc,编译出来的汇编是不同的。riscv64-unknown-elf-gcc-8.3.0hello.c -S -o hello.s

      .file   "hello.c"
         .option nopic
         .text
         .section      .rodata
         .align3
.LC0:
         .string "Hello World!"
         .text
         .align1
         .globlmain
         .type   main, @function
main:
         addi    sp,sp,-16
         sd      ra,8(sp)
         sd      s0,0(sp)
         addi    s0,sp,16
         lui   a5,%hi(.LC0)
         addi    a0,a5,%lo(.LC0)
         call    puts
         li      a5,0
         mv      a0,a5
         ld      ra,8(sp)
         ld      s0,0(sp)
         addi    sp,sp,16
         jr      ra
         .size   main, .-main
         .ident"GCC: (GNU) 8.3.0"
~riscv32-unknown-elf-gcc hello.c -S -o hello1.s

    .file    "hello.c"
   .option nopic
   .text
   .section    .rodata
   .align    2
.LC0:
   .string    "Hello World!"
   .text
   .align    1
   .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    puts
   li    a5,0
   mv    a0,a5
   lw    ra,12(sp)
   lw    s0,8(sp)
   addi    sp,sp,16
   jr    ra
   .size    main, .-main
   .ident    "GCC: (GNU) 8.3.0"RV32I 为程序和数据分配内存。图中的顶部是高地址,底部是低地址。
在 RISC-V 软件规范中,栈指针(sp)从 0xbffffff0 开始向下增加;
程序代码段从 0x00010000 开始,包括静态连接库;
程序代码段结束后是静态数据区,在这个例子中假设从 0x10000000 开始;
而后是动态数据区,由 C 语言中的alloc()函数分配,向上增加,其中包含动态连接库。

.file    "hello.c"
   .option nopic
   .text
   .section    .rodata
   .align    2 //4字节对齐

.LC0:
   .string    "Hello World!"
   .text
   .align    1
   .globl    main
   .type    main, @function

main:
   addi    sp,sp,-16 //sp=x2, 调整栈指针,分配栈栈
   sw    ra,12(sp) //保存函数返回地址,就是main函数的入口地址
   sw    s0,8(sp) //s0=x8,保存s0,帧指针
   addi    s0,sp,16 //s0=栈顶地址
   lui    a5,%hi(.LC0) //计算LC0的地址,a0,…a7保存函数参数地址
   addi    a0,a5,%lo(.LC0)
   call    puts //调用puts函数,输出hello world
   li    a5,0 //读取当即数,a5=0
   mv    a0,a5 //a0=0,恢复参数地址为0 lw    ra,12(sp) //恢复返回地址
   lw    s0,8(sp) //恢复s0,帧指针
   addi    sp,sp,16 //恢复sp
   jr    ra// 跳转到ra地址
   .size    main, .-main
   .ident    "GCC: (GNU) 8.3.0"

页: [1]
查看完整版本: RiscV汇编介绍(2)-编译过程