Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arm Assembly - Calling function with more than 4 arguments

I know that when calling a function in assembly r0 contains the first argument up to r3 being the fourth. I know that when it goes beyond four the stack pointer is used but I'm not too sure on the specifics. Does r0-r3 still hold the first four and the rest goes on the stack? I'm looking at the following piece of assembly trying to understand what it's doing to call mach_msg (a function with seven arguments). On entry to this code, r0 and r1 contain the two arguments

var_38          = -0x38
var_34          = -0x34
var_30          = -0x30
var_2C          = -0x2C
var_24          = -0x24
var_20          = -0x20
var_18          = -0x18
var_14          = -0x14
var_10          = -0x10
var_C           = -0xC
00001220
00001220                 PUSH            {R7,LR}
00001222                 MOV             R7, SP
00001224                 SUB             SP, SP, #0x30
00001226                 MOV             R2, (_NDR_record_ptr - 0x1232) ; _NDR_record_ptr
0000122E                 ADD             R2, PC ; _NDR_record_ptr
00001230                 LDR             R2, [R2] ; _NDR_record
00001232                 LDR             R3, [R2]
00001234                 LDR             R2, [R2,#4]
00001236                 STR             R2, [SP,#0x38+var_10]
00001238                 MOVS            R2, #0x24 ; '$'
0000123A                 STR             R3, [SP,#0x38+var_14]
0000123C                 MOVS            R3, #0
0000123E                 STRB.W          R1, [SP,#0x38+var_C]
00001242                 MOVS            R1, #0x13
00001244                 STR             R1, [SP,#0x38+var_2C]
00001246                 MOVS            R1, #1
00001248                 STR             R0, [SP,#0x38+var_24]
0000124A                 MOV             R0, 0x1E84EA
00001252                 STR             R3, [SP,#0x38+var_20]
00001254                 STR             R3, [SP,#0x38+var_38]
00001256                 STR             R3, [SP,#0x38+var_34]
00001258                 STR             R0, [SP,#0x38+var_18]
0000125A                 STR             R3, [SP,#0x38+var_30]
0000125C                 ADD             R0, SP, #0x38+var_2C
0000125E                 BLX             _mach_msg
00001262                 ADD             SP, SP, #0x30
00001264                 POP             {R7,PC}

Here are the definitions for the stuff being called and used:

typedef struct {
    unsigned char       mig_vers;
    unsigned char       if_vers;
    unsigned char       reserved1;
    unsigned char       mig_encoding;
    unsigned char       int_rep;
    unsigned char       char_rep;
    unsigned char       float_rep;
    unsigned char       reserved2;
} NDR_record_t;
extern NDR_record_t NDR_record;
extern mach_msg_return_t    mach_msg(
                mach_msg_header_t *msg,
                mach_msg_option_t option,
                mach_msg_size_t send_size,
                mach_msg_size_t rcv_size,
                mach_port_name_t rcv_name,
                mach_msg_timeout_t timeout,
                mach_port_name_t notify);

From what I understand, the stack pointer is being reversed 48 bytes for variables. Is that 48 bytes for the extra 3 arguments or for all of them?

like image 816
user1000039 Avatar asked Nov 06 '11 16:11

user1000039


People also ask

How many arguments can a function call have?

Except for functions with variable-length argument lists, the number of arguments in a function call must be the same as the number of parameters in the function definition. This number can be zero. The maximum number of arguments (and corresponding parameters) is 253 for a single function.

Which ARM instruction is appropriate for calling a function?

ARM uses the branch and link instruction (BL) to call a function and moves the link register to the PC (MOV PC, LR) to return from a function. Code Example 6.20 shows the main function calling the simple function. main is the caller, and simple is the callee.

Can a function have too many arguments?

Many times, we tend to add too many parameters to a function. But that's not the best idea: on the contrary, when a function requires too many arguments, grouping them into coherent objects helps writing simpler code.

How do you call a function in assembly?

To call an external function, such as NetRun's "print_int", or a standard C library function like "exit", you need to tell the assembler the function is "extern". "extern" isn't actually an instruction--it doesn't show up in the disassembly--it's just a message to the assembler, often called a pseudoinstruction.


1 Answers

Of the 48 bytes, 12 are for the extra 3 parameters, and the others are for local variables. You can see this in the code where the function passes four parameters in r0 through r3, another in [SP,#0x38+var_38] (which if you do the math resolves to just [sp]), another in [sp,#4], and the last in [sp,#8].

like image 194
Raymond Chen Avatar answered Oct 06 '22 06:10

Raymond Chen