What order is in hand - parameters stored on the stack?

This is a homework question. I am trying to call a form function FOO(A,B,C,D,E,F) . The first four parameters are in the register r0-r3 . The last two are in r7 and r6 (respectively) so that they are back. How can I push parameters onto the stack so that they are in the correct order?

this is STMFD sp! {r0-r3} STMFD sp! {r0-r3} , then STMFD sp! {r7, r6, lr} STMFD sp! {r7, r6, lr} ? I use a full downward stack.

Are the diagrams on this site correct because when it is STMFD r13!, {r4-r7} should not r4 be where r7 if the lowest register is first stored?

+4
source share
4 answers

In ARM, the order of the register list does not matter. It will always store the beginning with the lowest register (R0, R1, R2, ...). The following equivalents (if accepted by the assembler):

 STMFD SP!, {R0-R3} STMFD SP!, {R3, R2, R1, R0} STMFD SP!, {R1-R2, R0, R3} 
+6
source

Kenny got the right answer, I think.

I also found documentation on this subject if you don't already have one: ARM describes the most common usage agreement here . This site also contains call information between C and ASM (which in turn illustrates call conventions).

+2
source

Why not just give it a try?

 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+ef); } 

with somewhat current gcc gives

 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 gives:

 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 

Since this is homework, I will leave it all up to you to find out if you can use one stm / push command with multiple registers (as mentioned in other answers, you DO NOT control the order on the multi-register stack) or several stm / push instructions with one register on. (or figure out how to make a test program that shows you the answer)

Knowing the agreement is good, but you can answer such questions without fully familiarizing yourself with the agreement, use a compiler or two that follow the agreement. In principle, do not assume that you know everything about the agreement from any sorting, for example, you did not tell us if a, b, c, d, e, f are 64-bit integers, double floats, bytes, halfwords , words, etc. How many things on the stack will definitely be affected by this, but in what order and regardless of whether you can use stm / push instructions with multiple registers to receive it, it will probably be consistent.

EDIT:

Yes, this web page is correct, you need to get and read ARM ARM (well, now for each family there is a separate ARM ARM (ARM Architectural Reference Manual)). They have instructions defined with pseudo code, etc. In this case:

 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). 
+1
source

Registers are transferred in order from smallest to highest, so R15 (if listed) will always be transmitted last. Lower case is also transferred to / from the smallest memory address.

+1
source

Source: https://habr.com/ru/post/1385999/


All Articles