2016-10-01 2 views
2

Я написал функцию сборки, которая отлично работает на iPhone 4 (32-разрядный код), а также на iPhone 6s (64-разрядный код). Я передаю четыре числа с плавающей запятой из вызывающей функции в объективе-с.return floats to object-c от функции сборки руки

Вот структура, которую я использую для 4 чисел с плавающей запятой и ниже, которая является прототипом функции - как она находится в верхней части моего объектного кода 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 значения с плавающей запятой передаются из кода object-c в код сборки через однопоточные регистры ARM S0-S4. Полученные результаты также передаются через S0-S4.

При работе с iPhone 4 код работает отлично (32-разрядный код). 4 значения с плавающей запятой передаются из кода obj-c в код сборки через однопоточные регистры ARM S0, S2, S4 и S6 (не знаю, почему пропускает нечетные регистры). Код работает нормально, но значения, возвращаемые в мою структуру obj-c, - это мусор.

Где/как передавать значения с плавающей запятой из 32-битного кода ARM, чтобы они возвращались в структуру obj-c?

спасибо, relayman357

P.S. Ниже приведен мой код сборки из моего файла 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 
+1

Напишите эквивалентный код C, а затем разоберите его. Где-то там вы не отвечаете потребностям ABI. – bbum

ответ

0

Ни одна из ваших функций не возвращает правильную структуру. Вам нужно понять ARM ABI. Вы можете начать с чтения iOS ABI Function Call Guide от Apple. Если после изучения ABI вы не понимаете, задайте новый вопрос, показывающий, что вы пробовали.

HTH

+0

UPDATE: Хорошо, я думаю, HTH поставил меня на правильный след - я еще не совсем там. Ниже я узнал, начиная с чтения iOS ABI Function Call Guide. Теперь я могу получить доступ ко всем параметрам, переданным в asm-код из кода asm. НО, я все еще не могу успешно вернуть значения из моего кода asm в свою структуру. – relayman357

+0

Я изменил структуру myValues, чтобы провести 6 поплавков. Первые 3 значения с плавающей запятой передаются в функцию сборки через регистры r1, r2 и r3. Это 32-битные регистры, а значения кодируются в формате IEEE 754 с одной плавающей запятой (в отладчике Xcode вы можете щелкнуть правой кнопкой мыши по регистру и выбрать «значение вида как» и выбрать float. Остальные 3 значения с плавающей запятой, которые пройдены из вызывающего кода вставляются в стек и готовы захватить со следующим кодом в функции сборки: – relayman357

+0

Ключи: 1) Признавая, что поплавки хранятся в 32-разрядных общих регистрах (r1-r3) в IEEE 754 Single , 2) При отладке вы можете посмотреть общие регистры и щелкнуть правой кнопкой мыши на «sp» и выбрать «просмотреть память sp», тогда вам нужно изменить просмотренную память (по какой-то причине она не переходит на адрес памяти в sp) до фактической сохраненной ячейки памяти sp. 3) Как только вы смотрите на правильный адрес: 3a) Sp указывает на прошедшее значение. 3b) Значения, расположенные в небольшом конце, например. «00 20 00 40» действительно «40 00 20 00» - это плавающий 2.002 – relayman357