I compiled same sample c file, but got very different asmbler code.
The c file is:
void my_print(char *fmt, ...){ *((volatile int *) 0x1000) =(int) &fmt;}
void test(void){ my_print("a", 1, 2, 3, 4, 5, 6, 7, 8, 9);
}
By armclang( ARM Compiler 6.01 (build 22)), command is as "armclang -mcpu=cortex-a53 --target=aarch64-arm-none-eabi test.c" , and the assemble code of my_print is like:
0000000000008000 <my_print>:
8000: d10303ff sub sp, sp, #0xc0
8004: 3d801fe7 str q7, [sp,#112]
8008: 3d801be6 str q6, [sp,#96]
800c: 3d8017e5 str q5, [sp,#80]
8010: 3d8013e4 str q4, [sp,#64]
8014: 3d800fe3 str q3, [sp,#48]
8018: 3d800be2 str q2, [sp,#32]
801c: 3d8007e1 str q1, [sp,#16]
8020: 3d8003e0 str q0, [sp]
8024: f9005be7 str x7, [sp,#176]
8028: f90057e6 str x6, [sp,#168]
802c: f90053e5 str x5, [sp,#160]
8030: f9004fe4 str x4, [sp,#152]
8034: f9004be3 str x3, [sp,#144]
8038: f90047e2 str x2, [sp,#136]
803c: f90043e1 str x1, [sp,#128]
8040: f9005fe0 str x0, [sp,#184] // Jerry: x0, i.e., the address of fmt, located at the bottom of the stack.
8044: 9102e3e0 add x0, sp, #0xb8
8048: 2a0003e8 mov w8, w0
804c: 321403e9 orr w9, wzr, #0x1000
8050: 2a0903e0 mov w0, w9
8054: b9000008 str w8, [x0]
8058: 910303ff add sp, sp, #0xc0
805c: d65f03c0 ret
For gcc(aarch64-none-elf-gcc, Linaro GCC 4.8.3), command as "aarch64-none-elf-gcc test.c -nostdlib", then the assemble code is like: 400024: d10343ff sub sp, sp, #0xd0
400024: d10343ff sub sp, sp, #0xd0
400028: f9004fe1 str x1, [sp,#152]
40002c: f90053e2 str x2, [sp,#160]
400030: f90057e3 str x3, [sp,#168]
400034: f9005be4 str x4, [sp,#176]
400038: f9005fe5 str x5, [sp,#184]
40003c: f90063e6 str x6, [sp,#192]
400040: f90067e7 str x7, [sp,#200]
400044: 3d8007e0 str q0, [sp,#16]
400048: 3d800be1 str q1, [sp,#32]
40004c: 3d800fe2 str q2, [sp,#48]
400050: 3d8013e3 str q3, [sp,#64]
400054: 3d8017e4 str q4, [sp,#80]
400058: 3d801be5 str q5, [sp,#96]
40005c: 3d801fe6 str q6, [sp,#112]
400060: 3d8023e7 str q7, [sp,#128]
400064: f90003e0 str x0, [sp] // Jerry : x0, i.e., the address of fmt, located at the top of the stack.
400068: d2820000 mov x0, #0x1000 // #4096
40006c: 910003e1 mov x1, sp
400070: b9000001 str w1, [x0]
400074: 910343ff add sp, sp, #0xd0
400078: d65f03c0 ret
The armclang is behavior is as expected? And gcc voilated Procedure Call Standard?
B.R
Jerry
Yes you're right thanks.That slipped my mind. I wonder what kind of an overhead all that stuff is, for instance va_list stores a lot of floating point registers and one might never access them. If one had a standards option to say one had to always use function prototypes the business could be done much more efficiently - the varadic parameters could be passed on the stack every time and accessing them would just get the next item off the stack. I think this is one of the nastier legacies of K&R C.