【问题标题】:return floats to objective-c from arm assembly function将浮点数从 arm 装配函数返回到 Objective-c
【发布时间】:2017-02-10 05:24:52
【问题描述】:

我编写了一个汇编函数,可以在 iPhone 4(32 位代码)和 iPhone 6s(64 位代码)上正常运行。我从 Objective-c 中的调用函数传入四个浮点数。

这是我用于 4 个浮点数的结构,下面是函数的原型 - 可以在我的 Objective-c 代码的顶部找到。

struct myValues{    // This is a structure.  It is used to conveniently group multiple data items logically.
    float A;        // I am using it here because i want to return multiple float values from my ASM code
    float B;        // They get passed in via S0, S1, S2 etc. and they come back out that way too
    float number;
    float divisor;  //gonna be 2.0
}myValues;

struct myValues my_asm(float e, float f, float g, float h);  //  Prototype for the ASM function

在我的 Objective-c 代码中,我这样调用我的汇编函数:

myValues = my_asm(myValues.A, myValues.B, myValues.number,myValues.divisor);   // ASM function

在 iPhone 6S 上运行时,代码运行起来就像一个冠军(64 位代码)。 4 个浮点值通过 ARM 单浮点寄存器 S0-S4 从 Objective-C 代码传递到汇编代码。返回的结果也通过 S0-S4 传递。

在 iPhone 4 上运行时,代码也可以正常运行(32 位代码)。 4 个浮点值通过 ARM 单浮点寄存器 S0、S2、S4 和 S6 从 obj-c 代码传递到汇编代码(不知道为什么会跳过奇数寄存器)。代码运行良好,但返回到我的 obj-c 结构的值是垃圾。

我在哪里/如何从 ARM 32 位代码中传递浮点值,以便它们返回到 obj-c 结构中?

谢谢, 中继器357

附言下面是我的 Xcode S 文件中的汇编代码。

.ios_version_min 9, 0
.globl  _my_asm
.align  2

#ifdef __arm__
.thumb_func _my_asm
.syntax unified
.code 16

_my_asm:                   // 32 bit code
// S0 = A, S2 = B, S4 = Number, S6 = 2.0   - parameters passed in when called by the function
vadd.f32 s0, s0, s2 
vdiv.f32 s0, s0, s6   
vdiv.f32 s1, s4, s0   
vcvt.u32.f32 r0,s0
bx lr
//ret

#else
_my_asm:                  // 64 bit code
//add W0, W0, W1
; S0 = A, S1 = B, S2 = Number, S3 = 2.0  parameters passed in when called by the function
fadd s0, s0, s1  
fdiv s0, s0, s3  
fdiv s1, s2, s0  
ret

#endif

【问题讨论】:

  • 编写等效的C代码,然后反汇编。那里的某个地方无法满足 ABI 的需求。

标签: ios objective-c iphone assembly arm


【解决方案1】:

您的两个函数都没有正确返回结构。您需要了解 ARM ABI。您可以从阅读 Apple 的 iOS ABI Function Call Guide 开始。如果在学习 ABI 后您不明白,请提出一个新问题来说明您的尝试。

HTH

【讨论】:

  • 更新:好的,我认为 HTH 让我走上了正确的道路——我只是还没到那一步。以下是我从阅读 iOS ABI 函数调用指南开始学到的东西。现在我可以从 asm 代码中访问传递给 asm 代码的所有参数。但是,我仍然无法成功地将我的 asm 代码中的值恢复到我的结构中。
  • 我将“myValues”结构更改为容纳 6 个浮点数。前 3 个浮点值通过寄存器 r1、r2 和 r3 传递给汇编函数。这些是 32 位寄存器,值以 IEEE 754 单浮点格式编码(在 Xcode 调试器中,您可以右键单击寄存器并选择“view value as”并选择 float。其余 3 个浮点值通过从调用代码被压入堆栈并准备在汇编函数中使用以下代码抓取:
  • 关键:1) 认识到浮点数存储在 IEEE 754 Single 的 32 位通用寄存器 (r1-r3) 中。 2)调试的时候可以查看通用寄存器,右键“sp”,选择“查看sp的内存”,那么就得把查看的内存改一下(由于某种原因,它没有去到里面的内存地址sp) 到实际存储的内存位置是 sp。 3) 一旦你看到正确的地址: 3a) sp 指向最后一个传递的值。 3b)值以小端存储 - 例如"00 20 00 40" 真的是 "40 00 20 00" - 这是 float 2.002
  • // 在此处添加 Prolog 代码以播放漂亮的 vmov s1, r1 // 将 IEEE 754 编码的第一个浮点数放入 S1 vmov s2, r2 // 取第二个浮点数并放入 S2vmov s3, r3 vldr s6 , [sp] vldr s5, [sp, #4] // 将第 5 个浮点数加载到 S5 (333.0) vldr s4, [sp, #8] // 将第 4 个浮点数加载到 S4 (444.0) vdiv.f32 s3, s0 , s0 //result S3 = 1.0 改变值 vadd.f32 s0, s5, s3 // 334.0 vadd.f32 s1, s1, s1 // 4.2 vadd.f32 s2, s2, s1 // 9.438 vstr s0, [sp] vstr s1, [sp, #4] vstr s2, [sp, #8] // 在这里添加 Epilog 代码,玩起来不错
  • 这很难理解,但我认为您仍然无法回答一个明显的问题:函数如何返回大于寄存器容纳的结构值?现在有不止一个可能的答案,你能想到任何一个吗?每个 ABI 都有自己的选择,如果您在文档中找不到它,请以不同的方式处理它:在 Obj-C 中编写您的函数并在 Xcode 中反汇编它,然后查看它如何返回值。
猜你喜欢
  • 2015-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
相关资源
最近更新 更多