В Arm какой порядок хранятся параметры в стеке? - PullRequest
5 голосов
/ 13 декабря 2011

Это домашнее задание.Я пытаюсь вызвать функцию вида FOO(A,B,C,D,E,F).Первые четыре параметра находятся в регистре r0-r3.Последние два в r7 и r6 (соответственно), поэтому они в обратном направлении.Как я могу поместить параметры в стек, чтобы они были в правильном порядке?

это STMFD sp! {r0-r3} тогда STMFD sp! {r7, r6, lr}?Я использую полный нисходящий стек.

Диаграммы на этом сайте правильные, потому что когда это происходит, STMFD r13!, {r4-r7} не должно быть r4 там, где r7, если самый низкийРегистр хранится первым?

Ответы [ 4 ]

7 голосов
/ 13 декабря 2011

В ARM порядок списка регистров не имеет значения. Он всегда будет храниться, начиная с самого нижнего регистра (R0, R1, R2, ...). Все следующие значения эквивалентны (если они приняты ассемблером):

STMFD SP!, {R0-R3}
STMFD SP!, {R3, R2, R1, R0}
STMFD SP!, {R1-R2, R0, R3}
2 голосов
/ 13 декабря 2011

Почему бы просто не попробовать?

unsigned int foo ( unsigned int a, unsigned int b, unsigned int c,
unsigned int d, unsigned int e, unsigned int f )
{

    return(a+b+c+d+e-f);

}

с несколько текущим gcc дает

00000000 <foo>:
   0:   e0810000    add r0, r1, r0
   4:   e080c002    add ip, r0, r2
   8:   e08c1003    add r1, ip, r3
   c:   e59d3000    ldr r3, [sp]
  10:   e59d2004    ldr r2, [sp, #4]
  14:   e0810003    add r0, r1, r3
  18:   e0620000    rsb r0, r2, r0
  1c:   e12fff1e    bx  lr

llvm дает:

00000000 <foo>:
   0:   e0810000    add r0, r1, r0
   4:   e59d1000    ldr r1, [sp]
   8:   e0800002    add r0, r0, r2
   c:   e59d2004    ldr r2, [sp, #4]
  10:   e0800003    add r0, r0, r3
  14:   e0800001    add r0, r0, r1
  18:   e0400002    sub r0, r0, r2
  1c:   e1a0f00e    mov pc, lr

Так как это домашняя работа, япредоставим вам возможность выяснить, можете ли вы использовать одну инструкцию stm / push с несколькими регистрами (как уже упоминалось в других ответах, вы НЕ управляете порядком в стеке с несколькими регистрами) или несколькими инструкциями stm / push с одним регистромпер.(или выясните, как создать тестовую программу, которая покажет вам ответ)

Знание соглашения - это хорошо, но вы можете отвечать на подобные вопросы без полного прочтения соглашения, использовать один или два компилятора, которыеследовать конвенции.По сути, не думайте, что вы знаете все о соглашении из какой-то разборки, например, вы не сказали нам, если a, b, c, d, e, f являются 64-битными целыми числами, двойными числами с плавающей запятой, байтами, полусловами, словами и т. Д. Скольковещи в стеке, безусловно, будут затронуты этим, но в каком порядке и можете ли вы использовать команды stm / push с несколькими регистрами, чтобы получить их там, вероятно, будет согласованным.

РЕДАКТИРОВАТЬ:

Да, эта веб-страница правильная, вам нужно получить и прочитать ARM ARM (ну, теперь есть отдельное ARM ARM (ARM Architectural Reference Manual) для каждого семейства).Эти инструкции имеют псевдокод и т. Д. В этом случае:

The registers are stored in sequence, the lowest-numbered register to the lowest
memory address (start_address), through to the highest-numbered register to the
highest memory address (end_address).
2 голосов
/ 13 декабря 2011

Кенни получил правильный ответ, я думаю.

Я также нашел некоторую документацию по этому вопросу, если у вас ее еще нет: ARM описывает наиболее распространенное соглашение о вызовах здесь . Этот веб-сайт также содержит подробную информацию о вызовах между C и ASM (что, в свою очередь, иллюстрирует соглашения о вызовах).

1 голос
/ 14 февраля 2018

Регистры передаются в порядке убывания, поэтому R15 (если есть в списке) всегда передается последним. Нижний регистр также передается на / с самого низкого адреса памяти.

...