level 5
桥后看桥
楼主
首先是一段很简单的代码
```c++
// 初始化 sp 寄存器
extern "C" void _start() {asm volatile("ldr x11, =stack_top\n\t""mov sp, x11\n\t""bl main\n\t");}
// qemu 中的串口地址,用于串口输出
void putc(char character) { *(char *)0x9000000 = character; }
// 要传递的结构体
struct param_t {char data[15];};
// 测试函数
void callee(param_t var) { putc('a');
void main() {putc('0');callee({});putc('1');}
```
编译:
aarch64-elf-g++ -ffreestanding -nostdlib -Wl,--entry=_start -Wl,--section-start=.text=0x40100000 -Wl,--defsym=stack_top=0x40101000 -o aarch64_minimal main.cpp
在 qemu 中运行:
qemu-system-aarch64 -nographic -serial stdio -monitor telnet::2333,server,nowait -m 1024M -machine virt -cpu cortex-a72 -kernel aarch64_minimal
预期的输出应该是 `0a1`,但是当 param_t 结构体中 data 数组的大小为 15 时只能输出 `0`,改成 16 则能输出符合预期的结果。
楼主的初步排查结论:
1. 与 aapcs64 相关,涉及到结构体参数的传递规范,参考:https://github.com/ARM-software/abi-aa/blob/2982a9f3b512a5bfdc9e3fea5d3b298f9165c36b/aapcs64/aapcs64.rst#682parameter-passing-rules2. 不涉及到浮点寄存器
3. 栈的相关设置没有问题
这是对应的反汇编代码
```shell
aarch64_minimal:file format elf64-littleaarch64
Disassembly of section .text:
0000000040100000 <_start>:
40100000: 58000d4b ldrx11, 0x401001a8
40100004: 9100017f movsp, x11
40100008: 94000053 bl0x40100154
4010000c: d503201f nop
40100010: d65f03c0 ret
0000000040100014 <_Z4putcc>:
40100014: d10043ff subsp, sp, #0x10
40100018: 39003fe0 strbw0, [sp, #0xf]
4010001c: d2a12000 movx0, #0x9000000 // =150994944
40100020: 39403fe1 ldrbw1, [sp, #0xf]
40100024: 39000001 strbw1, [x0]
40100028: d503201f nop
4010002c: 910043ff addsp, sp, #0x10
40100030: d65f03c0 ret
0000000040100034 <_Z6callee7param_t>:
40100034: a9be7bfd stpx29, x30, [sp, #-0x20]!
40100038: 910003fd movx29, sp
4010003c: aa0003e2 movx2, x0
40100040: aa0103e0 movx0, x1
40100044: f9000be2 strx2, [sp, #0x10]
40100048: 92401c03 andx3, x0, #0xff
4010004c: 394063e1 ldrbw1, [sp, #0x18]
40100050: 52800002 movw2, #0x0 // =0
40100054: 0a020021 andw1, w1, w2
40100058: 2a0103e2 movw2, w1
4010005c: 2a0303e1 movw1, w3
40100060: 2a010041 orrw1, w2, w1
40100064: 390063e1 strbw1, [sp, #0x18]
40100068: d348fc01 lsrx1, x0, #8
4010006c: 92401c23 andx3, x1, #0xff
40100070: 394067e1 ldrbw1, [sp, #0x19]
40100074: 52800002 movw2, #0x0 // =0
40100078: 0a020021 andw1, w1, w2
4010007c: 2a0103e2 movw2, w1
40100080: 2a0303e1 movw1, w3
40100084: 2a010041 orrw1, w2, w1
40100088: 390067e1 strbw1, [sp, #0x19]
4010008c: d350fc01 lsrx1, x0, #16
40100090: 92401c23 andx3, x1, #0xff
40100094: 39406be1 ldrbw1, [sp, #0x1a]
40100098: 52800002 movw2, #0x0 // =0
4010009c: 0a020021 andw1, w1, w2
401000a0: 2a0103e2 movw2, w1
401000a4: 2a0303e1 movw1, w3
401000a8: 2a010041 orrw1, w2, w1
401000ac: 39006be1 strbw1, [sp, #0x1a]
401000b0: d358fc01 lsrx1, x0, #24
401000b4: 92401c23 andx3, x1, #0xff
401000b8: 39406fe1 ldrbw1, [sp, #0x1b]
401000bc: 52800002 movw2, #0x0 // =0
401000c0: 0a020021 andw1, w1, w2
401000c4: 2a0103e2 movw2, w1
401000c8: 2a0303e1 movw1, w3
401000cc: 2a010041 orrw1, w2, w1
401000d0: 39006fe1 strbw1, [sp, #0x1b]
401000d4: d360fc01 lsrx1, x0, #32
401000d8: 92401c23 andx3, x1, #0xff
401000dc: 394073e1 ldrbw1, [sp, #0x1c]
401000e0: 52800002 movw2, #0x0 // =0
401000e4: 0a020021 andw1, w1, w2
401000e8: 2a0103e2 movw2, w1
401000ec: 2a0303e1 movw1, w3
401000f0: 2a010041 orrw1, w2, w1
401000f4: 390073e1 strbw1, [sp, #0x1c]
401000f8: d368fc01 lsrx1, x0, #40
401000fc: 92401c23 andx3, x1, #0xff
40100100: 394077e1 ldrbw1, [sp, #0x1d]
40100104: 52800002 movw2, #0x0 // =0
40100108: 0a020021 andw1, w1, w2
4010010c: 2a0103e2 movw2, w1
40100110: 2a0303e1 movw1, w3
40100114: 2a010041 orrw1, w2, w1
40100118: 390077e1 strbw1, [sp, #0x1d]
4010011c: d370fc00 lsrx0, x0, #48
40100120: 92401c02 andx2, x0, #0xff
40100124: 39407be0 ldrbw0, [sp, #0x1e]
40100128: 52800001 movw1, #0x0 // =0
4010012c: 0a010000 andw0, w0, w1
40100130: 2a0003e1 movw1, w0
40100134: 2a0203e0 movw0, w2
40100138: 2a000020 orrw0, w1, w0
4010013c: 39007be0 strbw0, [sp, #0x1e]
40100140: 52800c20 movw0, #0x61 // =97
40100144: 97ffffb4 bl0x40100014 <_Z4putcc>
40100148: d503201f nop
4010014c: a8c27bfd ldpx29, x30, [sp], #0x20
40100150: d65f03c0 ret
0000000040100154 :
40100154: a9be7bfd stpx29, x30, [sp, #-0x20]!
40100158: 910003fd movx29, sp
4010015c: 52800600 movw0, #0x30 // =48
40100160: 97ffffad bl0x40100014 <_Z4putcc>
40100164: 910043e0 addx0, sp, #0x10
40100168: 4f00041f moviv31.4s, #0x0
4010016c: 9e6603e1 fmovx1, d31
40100170: f9000001 strx1, [x0]
40100174: 9e6603e1 fmovx1, d31
40100178: f8007001 sturx1, [x0, #0x7]
4010017c: f9400be2 ldrx2, [sp, #0x10]
40100180: f9400fe0 ldrx0, [sp, #0x18]
40100184: d340dc01 ubfxx1, x0,
#0, #
56
40100188: aa0203e0 movx0, x2
4010018c: 97ffffaa bl0x40100034 <_Z6callee7param_t>
40100190: 52800620 movw0, #0x31 // =49
40100194: 97ffffa0 bl0x40100014 <_Z4putcc>
40100198: d503201f nop
4010019c: a8c27bfd ldpx29, x30, [sp], #0x20
401001a0: d65f03c0 ret
401001a4: 00000000 udf#0x0
401001a8: 00 10 10 40 .word0x40101000
401001ac: 00 00 00 00 .word0x00000000
```
2025年06月23日 03点06分
1
```c++
// 初始化 sp 寄存器
extern "C" void _start() {asm volatile("ldr x11, =stack_top\n\t""mov sp, x11\n\t""bl main\n\t");}
// qemu 中的串口地址,用于串口输出
void putc(char character) { *(char *)0x9000000 = character; }
// 要传递的结构体
struct param_t {char data[15];};
// 测试函数
void callee(param_t var) { putc('a');
void main() {putc('0');callee({});putc('1');}
```
编译:
aarch64-elf-g++ -ffreestanding -nostdlib -Wl,--entry=_start -Wl,--section-start=.text=0x40100000 -Wl,--defsym=stack_top=0x40101000 -o aarch64_minimal main.cpp
在 qemu 中运行:
qemu-system-aarch64 -nographic -serial stdio -monitor telnet::2333,server,nowait -m 1024M -machine virt -cpu cortex-a72 -kernel aarch64_minimal
预期的输出应该是 `0a1`,但是当 param_t 结构体中 data 数组的大小为 15 时只能输出 `0`,改成 16 则能输出符合预期的结果。
楼主的初步排查结论:
1. 与 aapcs64 相关,涉及到结构体参数的传递规范,参考:https://github.com/ARM-software/abi-aa/blob/2982a9f3b512a5bfdc9e3fea5d3b298f9165c36b/aapcs64/aapcs64.rst#682parameter-passing-rules2. 不涉及到浮点寄存器
3. 栈的相关设置没有问题
这是对应的反汇编代码
```shell
aarch64_minimal:file format elf64-littleaarch64
Disassembly of section .text:
0000000040100000 <_start>:
40100000: 58000d4b ldrx11, 0x401001a8
40100004: 9100017f movsp, x11
40100008: 94000053 bl0x40100154
4010000c: d503201f nop
40100010: d65f03c0 ret
0000000040100014 <_Z4putcc>:
40100014: d10043ff subsp, sp, #0x10
40100018: 39003fe0 strbw0, [sp, #0xf]
4010001c: d2a12000 movx0, #0x9000000 // =150994944
40100020: 39403fe1 ldrbw1, [sp, #0xf]
40100024: 39000001 strbw1, [x0]
40100028: d503201f nop
4010002c: 910043ff addsp, sp, #0x10
40100030: d65f03c0 ret
0000000040100034 <_Z6callee7param_t>:
40100034: a9be7bfd stpx29, x30, [sp, #-0x20]!
40100038: 910003fd movx29, sp
4010003c: aa0003e2 movx2, x0
40100040: aa0103e0 movx0, x1
40100044: f9000be2 strx2, [sp, #0x10]
40100048: 92401c03 andx3, x0, #0xff
4010004c: 394063e1 ldrbw1, [sp, #0x18]
40100050: 52800002 movw2, #0x0 // =0
40100054: 0a020021 andw1, w1, w2
40100058: 2a0103e2 movw2, w1
4010005c: 2a0303e1 movw1, w3
40100060: 2a010041 orrw1, w2, w1
40100064: 390063e1 strbw1, [sp, #0x18]
40100068: d348fc01 lsrx1, x0, #8
4010006c: 92401c23 andx3, x1, #0xff
40100070: 394067e1 ldrbw1, [sp, #0x19]
40100074: 52800002 movw2, #0x0 // =0
40100078: 0a020021 andw1, w1, w2
4010007c: 2a0103e2 movw2, w1
40100080: 2a0303e1 movw1, w3
40100084: 2a010041 orrw1, w2, w1
40100088: 390067e1 strbw1, [sp, #0x19]
4010008c: d350fc01 lsrx1, x0, #16
40100090: 92401c23 andx3, x1, #0xff
40100094: 39406be1 ldrbw1, [sp, #0x1a]
40100098: 52800002 movw2, #0x0 // =0
4010009c: 0a020021 andw1, w1, w2
401000a0: 2a0103e2 movw2, w1
401000a4: 2a0303e1 movw1, w3
401000a8: 2a010041 orrw1, w2, w1
401000ac: 39006be1 strbw1, [sp, #0x1a]
401000b0: d358fc01 lsrx1, x0, #24
401000b4: 92401c23 andx3, x1, #0xff
401000b8: 39406fe1 ldrbw1, [sp, #0x1b]
401000bc: 52800002 movw2, #0x0 // =0
401000c0: 0a020021 andw1, w1, w2
401000c4: 2a0103e2 movw2, w1
401000c8: 2a0303e1 movw1, w3
401000cc: 2a010041 orrw1, w2, w1
401000d0: 39006fe1 strbw1, [sp, #0x1b]
401000d4: d360fc01 lsrx1, x0, #32
401000d8: 92401c23 andx3, x1, #0xff
401000dc: 394073e1 ldrbw1, [sp, #0x1c]
401000e0: 52800002 movw2, #0x0 // =0
401000e4: 0a020021 andw1, w1, w2
401000e8: 2a0103e2 movw2, w1
401000ec: 2a0303e1 movw1, w3
401000f0: 2a010041 orrw1, w2, w1
401000f4: 390073e1 strbw1, [sp, #0x1c]
401000f8: d368fc01 lsrx1, x0, #40
401000fc: 92401c23 andx3, x1, #0xff
40100100: 394077e1 ldrbw1, [sp, #0x1d]
40100104: 52800002 movw2, #0x0 // =0
40100108: 0a020021 andw1, w1, w2
4010010c: 2a0103e2 movw2, w1
40100110: 2a0303e1 movw1, w3
40100114: 2a010041 orrw1, w2, w1
40100118: 390077e1 strbw1, [sp, #0x1d]
4010011c: d370fc00 lsrx0, x0, #48
40100120: 92401c02 andx2, x0, #0xff
40100124: 39407be0 ldrbw0, [sp, #0x1e]
40100128: 52800001 movw1, #0x0 // =0
4010012c: 0a010000 andw0, w0, w1
40100130: 2a0003e1 movw1, w0
40100134: 2a0203e0 movw0, w2
40100138: 2a000020 orrw0, w1, w0
4010013c: 39007be0 strbw0, [sp, #0x1e]
40100140: 52800c20 movw0, #0x61 // =97
40100144: 97ffffb4 bl0x40100014 <_Z4putcc>
40100148: d503201f nop
4010014c: a8c27bfd ldpx29, x30, [sp], #0x20
40100150: d65f03c0 ret
0000000040100154 :
40100154: a9be7bfd stpx29, x30, [sp, #-0x20]!
40100158: 910003fd movx29, sp
4010015c: 52800600 movw0, #0x30 // =48
40100160: 97ffffad bl0x40100014 <_Z4putcc>
40100164: 910043e0 addx0, sp, #0x10
40100168: 4f00041f moviv31.4s, #0x0
4010016c: 9e6603e1 fmovx1, d31
40100170: f9000001 strx1, [x0]
40100174: 9e6603e1 fmovx1, d31
40100178: f8007001 sturx1, [x0, #0x7]
4010017c: f9400be2 ldrx2, [sp, #0x10]
40100180: f9400fe0 ldrx0, [sp, #0x18]
40100184: d340dc01 ubfxx1, x0,
#0, #
56
40100188: aa0203e0 movx0, x2
4010018c: 97ffffaa bl0x40100034 <_Z6callee7param_t>
40100190: 52800620 movw0, #0x31 // =49
40100194: 97ffffa0 bl0x40100014 <_Z4putcc>
40100198: d503201f nop
4010019c: a8c27bfd ldpx29, x30, [sp], #0x20
401001a0: d65f03c0 ret
401001a4: 00000000 udf#0x0
401001a8: 00 10 10 40 .word0x40101000
401001ac: 00 00 00 00 .word0x00000000
```