首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >臂参数传递

臂参数传递
EN

Stack Overflow用户
提问于 2016-03-11 15:17:18
回答 1查看 473关注 0票数 1

我试图写一个ARM程序,它接受三个数字,并计算判别。它有两个源文件,driver.s & prog3.s。我知道如何找到判别,但如何将A、B、&C值从主函数传递到描述函数中?到目前为止,我已经输入了代码.

MAIN() driver.s

代码语言:javascript
复制
avalue  .reg    r0
bvalue  .req    r1
cvalue  .req    r2
final   .req    r3
loopcount   .req    r4

readA:
.ascii  “%d”
readB:
.ascii  “%d”
readC:  
.ascii  “%d”

addressReadA:   .word   readA
addressReadB:   .word   readB
addressReadC:   .word   readC

main:
ldr avalue, addressReadA    @ load in avalue
ldr bvalue, addressReadB    @ load in bvalue
ldr cvalue, addressReadC    @ load in cvalue

DISCRIM()方案3.s

代码语言:javascript
复制
avalue  .reg    r0
bvalue  .req    r1
cvalue  .req    r2
final   .req    r3

discrim:
mul bvalue, bvalue, bvalue      @ square bvalue
mul avalue, avalue, #4      @ multiply avalue by 4
mul cvalue, avalue, cvalue      @ multiply avalue by cvalue
add final, bvalue, cvalue       @ calculated discriminant 
EN

回答 1

Stack Overflow用户

发布于 2016-03-12 16:56:55

遵循C编译器使用的调用约定并不是个坏主意,尤其是如果您从纯汇编程序转到C和asm混合程序,您已经有了这种经验。并且/或您可能会在所使用的调用约定中看到简单和智慧。

您如何知道编译器的调用约定是什么? 1)阅读手册/文档和google。2)试试看。Prototype一个函数,它类似于操作数、操作数的类型和返回值,并给它提供真实的数字,并查看它产生了什么。

编译到asm有时是有效的,但是使用伪指令和汇编程序所做的其他事情,我更喜欢集成而不是编译到asm。

代码语言:javascript
复制
unsigned int fun ( unsigned int a, unsigned int b, unsigned int c );
unsigned int test ( void )
{
    return(fun(1,2,3));
}

当前使用gnu的结果是

代码语言:javascript
复制
00000000 <test>:
   0:   e92d4010    push    {r4, lr}
   4:   e3a02003    mov r2, #3
   8:   e3a01002    mov r1, #2
   c:   e3a00001    mov r0, #1
  10:   ebfffffe    bl  0 <fun>
  14:   e8bd4010    pop {r4, lr}
  18:   e12fff1e    bx  lr

编译器和目标的每个组合都可能有不同的调用约定,因此没有理由假定同一编译器的不同编译器或版本使用相同的约定。ARM,MIPS,以及毫无疑问的其他人试图帮助/鼓励/建议使用一个调用约定,而一些编译器只是遵循这一点,为什么不这样做呢?

在约定中,规则有很多例外情况,但是对于ARM来说,前四个寄存器的参数值最多为4个,在这种情况下,最多为4个有符号或无符号整数,或至多4个小于或等于32位量的整数(浮点数可创建异常),前四个通用的回归器用于第一个参数r0,用于第二个参数,依此类推。目前,标准在64位边界上保持堆栈对齐。

所以我们看到,第一个参数确实放在r0中,第二个参数放在r1中,第三个参数放在r2中,很明显,您不必按照这个顺序排列这三个指令,这并不重要。

因为这个函数正在调用另一个函数,它必须在lr中保留它的返回值,所以它会在堆栈上保持堆栈对齐,因为标准说,为了在64位边界上保持堆栈对齐,他们在堆栈r4上推送另一个寄存器是任意的,它可以是任意的寄存器,这是工具选择的寄存器。

因为标准要求在r0中返回,所以实现这些函数之一的代码。

代码语言:javascript
复制
    unsigned int fun ( unsigned int a, unsigned int b, unsigned int c )
    {
        return(a+b^c);
    }

00000000 <fun>:
   0:   e0800001    add r0, r0, r1
   4:   e0200002    eor r0, r0, r2
   8:   e12fff1e    bx  lr

现在非常有趣的是,我看到编译器没有对调用进行尾优化,它可能没有保存lr,并且做了一个分支来好玩,因为r0中的返回值也是test()在同一个寄存器中返回的。真的有点困惑,因为没有发生这种事。

但是您可以看到返回值确实保留在r0中,按照惯例,我们不需要保存r0-r3,而这些函数不是。

如果您将测试更改为

代码语言:javascript
复制
unsigned int fun ( unsigned int a, unsigned int b, unsigned int c );
unsigned int test ( void )
{
    return(fun(1,2,3)+7);
}

然后,它不能尾巴优化,也显示返回寄存器,所以你不必创建一个有趣()函数来查看它。

代码语言:javascript
复制
00000000 <test>:
   0:   e92d4010    push    {r4, lr}
   4:   e3a02003    mov r2, #3
   8:   e3a01002    mov r1, #2
   c:   e3a00001    mov r0, #1
  10:   ebfffffe    bl  0 <fun>
  14:   e8bd4010    pop {r4, lr}
  18:   e2800007    add r0, r0, #7
  1c:   e12fff1e    bx  lr

您可以使用其他目标或其他编译器来做这种事情,没有理由假设一个目标和另一个目标具有相同的约定。

代码语言:javascript
复制
Disassembly of section .text:

00000000 <fun>:
   0:   0f 5e           add r14,    r15 
   2:   0f ed           xor r13,    r15 
   4:   30 41           ret         

0000000000000000 <fun>:
   0:   8d 04 37                lea    (%rdi,%rsi,1),%eax
   3:   31 d0                   xor    %edx,%eax
   5:   c3                      retq   

这个是基于堆栈的,而不是基于寄存器的。

代码语言:javascript
复制
Disassembly of section .text:

00000000 <_fun>:
   0:   1166            mov r5, -(sp)
   2:   1185            mov sp, r5
   4:   1d41 0004       mov 4(r5), r1
   8:   6d41 0006       add 6(r5), r1
   c:   1d40 0008       mov 10(r5), r0
  10:   7840            xor r1, r0
  12:   1585            mov (sp)+, r5
  14:   0087            rts pc

但是,如果这只是一个纯粹的组装项目,并且您不需要与编译后的输出进行接口,那么您想做什么就做什么,设计项目的一部分不仅仅是每个单独的函数,而是它们的交互方式,与C、Python或其他语言没有什么不同,您仍然需要为自己定义函数之间的接口。汇编语言并不是特别的或不同的,只是另一种语言而已。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35943763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档