【问题标题】:What does %call16 and .reloc mean in mips?mips 中的 %call16 和 .reloc 是什么意思?
【发布时间】:2020-06-26 16:19:42
【问题描述】:

我已经使用 gcc 编译器将 c 代码转换为 mips32,但有些部分我不明白。

这是c代码:

int main()
{
float fibSquared;
int F[10] = {0};
F[0] = 0;
F[1] = 1;
for(int i = 2; i < 10 ; i++)
F[i] = F[i-1] + F[i-2];
fibSquared = sqrt(F[9]);
printf("%f",fibSquared);
return 0;
}

这是 mips 代码:

.file   1 ""
    .section .mdebug.abi32
    .previous
    .nan    legacy
    .module fp=32
    .module nooddspreg
    .abicalls
    .rdata
    .align  2
$LC0:
    .ascii  "%f\000"
    .text
    .align  2
    .globl  main
    .set    nomips16
    .set    nomicromips
    .ent    main
    .type   main, @function
main:
    .frame  $fp,80,$31      # vars= 48, regs= 2/0, args= 16, gp= 8
    .mask   0xc0000000,-4
    .fmask  0x00000000,0
    .set    noreorder
    .cpload $25
    .set    nomacro
    addiu   $sp,$sp,-80
    sw  $31,76($sp)
    sw  $fp,72($sp)
    move    $fp,$sp
    .cprestore  16
    movz    $31,$31,$0
    sw  $0,32($fp)
    sw  $0,36($fp)
    sw  $0,40($fp)
    sw  $0,44($fp)
    sw  $0,48($fp)
    sw  $0,52($fp)
    sw  $0,56($fp)
    sw  $0,60($fp)
    sw  $0,64($fp)
    sw  $0,68($fp)
    sw  $0,32($fp)
    li  $2,1            # 0x1
    sw  $2,36($fp)
    li  $2,2            # 0x2
    sw  $2,24($fp)
    b   $L2
    nop

$L3:
    lw  $2,24($fp)
    nop
    addiu   $2,$2,-1
    sll $2,$2,2
    addiu   $3,$fp,24
    addu    $2,$3,$2
    lw  $3,8($2)
    lw  $2,24($fp)
    nop
    addiu   $2,$2,-2
    sll $2,$2,2
    addiu   $4,$fp,24
    addu    $2,$4,$2
    lw  $2,8($2)
    nop
    addu    $3,$3,$2
    lw  $2,24($fp)
    nop
    sll $2,$2,2
    addiu   $4,$fp,24
    addu    $2,$4,$2
    sw  $3,8($2)
    lw  $2,24($fp)
    nop
    addiu   $2,$2,1
    sw  $2,24($fp)
$L2:
    lw  $2,24($fp)
    nop
    slt $2,$2,10
    bne $2,$0,$L3
    nop

    lw  $2,68($fp)
    nop
    mtc1    $2,$f0
    nop
    cvt.d.w $f0,$f0
    mov.d   $f12,$f0
    lw  $2,%call16(sqrt)($28)
    nop
    move    $25,$2
    .reloc  1f,R_MIPS_JALR,sqrt
1:  jalr    $25
    nop

    lw  $28,16($fp)
    cvt.s.d $f0,$f0
    swc1    $f0,28($fp)
    lwc1    $f0,28($fp)
    nop
    cvt.d.s $f0,$f0
    mfc1    $7,$f0
    mfc1    $6,$f1
    lw  $2,%got($LC0)($28)
    nop
    addiu   $4,$2,%lo($LC0)
    lw  $2,%call16(printf)($28)
    nop
    move    $25,$2
    .reloc  1f,R_MIPS_JALR,printf
1:  jalr    $25
    nop

    lw  $28,16($fp)
    move    $2,$0
    move    $sp,$fp
    lw  $31,76($sp)
    lw  $fp,72($sp)
    addiu   $sp,$sp,80
    j   $31
    nop

    .set    macro
    .set    reorder
    .end    main
    .size   main, .-main
    .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609"

这是我看不懂的部分:

    lw  $2,68($fp)
    nop
    mtc1    $2,$f0
    nop
    cvt.d.w $f0,$f0
    mov.d   $f12,$f0
    lw  $2,%call16(sqrt)($28)
    nop
    move    $25,$2
    .reloc  1f,R_MIPS_JALR,sqrt
1:  jalr    $25
    nop

    lw  $28,16($fp)
    cvt.s.d $f0,$f0
    swc1    $f0,28($fp)
    lwc1    $f0,28($fp)
    nop
    cvt.d.s $f0,$f0
    mfc1    $7,$f0
    mfc1    $6,$f1
    lw  $2,%got($LC0)($28)
    nop
    addiu   $4,$2,%lo($LC0)
    lw  $2,%call16(printf)($28)
    nop
    move    $25,$2
    .reloc  1f,R_MIPS_JALR,printf
1:  jalr    $25
    nop

    lw  $28,16($fp)
    move    $2,$0
    move    $sp,$fp
    lw  $31,76($sp)
    lw  $fp,72($sp)
    addiu   $sp,$sp,80
    j   $31
    nop

    .set    macro
    .set    reorder
    .end    main
    .size   main, .-main
    .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609"
  1. .reloc 是什么意思?
  2. %call16 是如何工作的?
  3. 变量fibSquared的对应值是多少?
  4. “printf”和“sqrt”函数是如何调用和执行的?

【问题讨论】:

标签: c assembly gcc mips mips32


【解决方案1】:

我想你和我上的课一样,因为我有同样的作业,所以我将分享我自己的理解,这可能会有所帮助。

对于%call16,如果您注意到括号之间的名称,C 代码使用的名称来自包含的文件,例如来自stdio.hprintf,来自math 文件的sqrt,所以它显然是在调用它们这样他就可以使用它们了。

关于.reloc,我注意到它们出现在%call16 之后并且被调用的函数被执行并且用于重新定位内存,所以我认为它会重新排序包含的文件以防止可能发生的任何损坏。

fibSquared 值位于mem[-12] (SW $3,8($2))$2=-20,然后它被移动到$f0 by(mtc1 $2,$f0)。在指令中,第二个par 是destination($f0)。它从int 转换为float in(cvt.d.w $f0,$f0)

这部分代码中执行的sqrt

lw  $2,%call16(sqrt)($28) \\ in this particular 
    nop
    move    $25,$2
    .reloc  1f,R_MIPS_JALR,sqrt
1:  jalr    $25
$25 at the beginning was chosen for cpload (.cpload $25) 
** printf :
lw  $2,%got($LC0)($28)
    nop
    addiu   $4,$2,%lo($LC0)
    lw  $2,%call16(printf)($28)\\ in this particular 
    nop
    move    $25,$2
    .reloc  1f,R_MIPS_JALR,printf
1:  jalr    $25

【讨论】:

  • 我不认为 对可能发生的任何损坏重新排序包含的文件。 有任何意义。那些 C .h 文件不包含在 asm 中。我不知道它做了什么,但它可能告诉汇编器发出链接器可能使用的重定位元数据,也许如果你静态链接它可以将jalr 放松为一个简单的@ 987654338@,而不是使用从 GOT 加载的指针。
  • @PeterCordes 谢谢你,其实你说的更有意义。
猜你喜欢
  • 1970-01-01
  • 2020-01-31
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多