0

我正在为我正在从事的项目学习 OR1K 汇编。clangLLVM用于为编译器提供前端和后端。我找到了这个链接,它几乎是我需要的一切,但是我正在查看的程序集里面有@hi@lo符号。我对这些“说明”有直观的理解,但最好获得官方解释它们的含义。

下面是为它生成的 C 和相应的汇编代码。我所说的装配线几乎在底部。这是他们的样子

l.sw    0(r1), r11
l.movhi r3, hi(.L.str@hi)
l.jal   printf
l.ori   r3, r3, lo(.L.str@lo)

C代码

#include <stdio.h>
#include <assert.h>

int sum(int a, int b) {
  return a + b;
}

int main(int argc, char** argv) {
  printf("Hello World! %d\n", sum(argc, 1));
  return 0;
}

汇编代码

    .text
    .file   "hello_world.ll"
    .globl  _Z3sumii
    .align  4
    .type   _Z3sumii,@function
_Z3sumii:                               # @_Z3sumii
    .cfi_startproc
# BB#0:                                 # %entry
    l.sw    -4(r1), r2
.Ltmp0:
    .cfi_offset 2, -4
    l.addi  r2, r1, 0
.Ltmp1:
    .cfi_def_cfa_register 2
    l.addi  r1, r1, -12
    l.sw    -8(r2), r3
    l.sw    -12(r2), r4
    l.lwz   r3, -8(r2)
    l.add   r11, r3, r4
    l.addi  r1, r2, 0
    l.jr    r9
    l.lwz   r2, -4(r1)
.Ltmp2:
    .size   _Z3sumii, .Ltmp2-_Z3sumii
    .cfi_endproc

    .globl  main
    .align  4
    .type   main,@function
main:                                   # @main
    .cfi_startproc
# BB#0:                                 # %entry
    l.sw    -4(r1), r9
.Ltmp3:
    .cfi_offset 9, -4
    l.sw    -8(r1), r2
.Ltmp4:
    .cfi_offset 2, -8
    l.addi  r2, r1, 0
.Ltmp5:
    .cfi_def_cfa_register 2
    l.addi  r13, r1, -32
    l.srli  r13, r13, 3
    l.slli  r1, r13, 3
    l.movhi r5, 0
    l.sw    20(r1), r5
    l.sw    16(r1), r3
    l.sw    8(r1), r4
    l.lwz   r3, 16(r1)
    l.jal   _Z3sumii
    l.addi  r4, r0, 1
    l.sw    0(r1), r11
    l.movhi r3, hi(.L.str@hi)
    l.jal   printf
    l.ori   r3, r3, lo(.L.str@lo)
    l.movhi r11, 0
    l.addi  r1, r2, 0
    l.lwz   r9, -4(r1)
    l.jr    r9
    l.lwz   r2, -8(r1)
.Ltmp6:
    .size   main, .Ltmp6-main
    .cfi_endproc

    .type   .L.str,@object          # @.str
    .section    .rodata.str1.1,"aMS",@progbits,1
.L.str:
    .asciz  "Hello World! %d\n"
    .size   .L.str, 17

任何帮助表示赞赏。

4

1 回答 1

2

像许多汇编语言一样,OpenRISC 只能使用 16 位立即数。因此,要进行加载,它首先加载高 16 位,然后对低 16 位执行或操作。在伪 C 中:

int32_t addr = &str;
register r3;
r3 = addr & 0xFFFF0000; /* load hi bits, note this is a 16 bit value */
r3 |= addr &0xFFFF; /* load the lo bits of addr, note again only a 16 bit value */

那么,在 r3 负载的任一侧调用 printf 到底是怎么回事?好吧,OpenRISC 有一个分支延迟槽。所以对 printf 的调用发生or 指令之后。

于 2015-10-06T04:04:11.650 回答