2016-09-10 1 views
1

Платформа: Cortex-M3В чем разница между функцией в коде сборки, которая возвращает значение, и значением, которое не возвращает значение?

IDE: Keil uVision5.10

Привет всем ~

Вот простой пример: Функция, которая не возвращает значение (скажем function1) в C код:

void add_one(int n) 
{ 
    int a = n+1; 
} 

Его сборка код:

ADDS r1,r0,#1 
BX  lr 

Функция, которая возвращает значение (скажем function2) в коде C:

int add_one(int n) 
{ 
    int a = n+1; 
    return a; 
} 

и его сборка код:

MOV  r1,r0 
ADDS r0,r1,#1 
BX  lr 

Насколько я могу видеть, единственное отличие состоит в том, что function2 перемещает параметр n из r0 и затем исчисляет вычисления, а функция1 вычисляет напрямую. Моя путаница в том, что две функции с обоих концов

BX  lr 

Я знаю, что эффект от кода, чтобы сделать программу переход к другому адресу, который содержал в регистре ЛО. Как может возвращать значение функции2? Что именно произошло?

+0

Ваше мнение о роли 'r0' верное. Вызывающая функция будет ожидать возвращаемое значение в 'r0' (если возвращаемое значение представляет собой целое число или указатель размера регистра) и будет игнорировать значение в' r0', если вызываемая функция ничего не возвращает ('void'). – EOF

+0

Если вы не знакомы, ключевой концепцией здесь является «[вызов конвенции] (https://en.wikipedia.org/wiki/Calling_convention)». – Notlikethat

+0

Если вы включили оптимизацию, функции будут одинаковыми. –

ответ

2

Возвращаемое значение сохраняется в R0. BX LR вернется к вызывающему абоненту, который знает, что функция возвращает что-то и теперь может получить его из регистра R0. Это соглашение между вызывающим и вызываемым называется «конвенция о вызове».

Вы должны проверить Procedure Call Standard for the ARM Architecture. Например, в разделе 5.4 «Возврат результата» говорится:

В r0 возвращается форма фундаментальных данных размера слова (например, int, float).

Это именно то, что вы видите.