%rax 作为函数返回值使用。
%rsp 栈指针寄存器,指向栈顶
%rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。
%rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防他被修改
%r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值
首先可以理解为 包装一个函数,入参为%rdi,%rsi,%rdx,%rcx,%r8,%r9,
其中rdi为上下文,其中保护各种寄存器,也就是后续的env;
rsi为翻译之后汇编执行代码的地址
PROLOGUE: [size=45]
0x7fcfd4000000: push %rbp #* 55//存储数据register rbp
0x7fcfd4000001: push %rbx #* 53//存储数据register rbx
0x7fcfd4000002: push %r12 #* 41 54//存储数据register r12
0x7fcfd4000004: push %r13 #* 41 55//存储数据register r13
0x7fcfd4000006: push %r14 #* 41 56//存储数据register r14
0x7fcfd4000008: push %r15 #* 41 57//存储数据register r15
0x7fcfd400000a: mov %rdi,%rbp #* 48 8b ef//把上下文保持到rbp
0x7fcfd400000d: add $0xfffffffffffffb78,%rsp #* 48 81 c4 78 fb ff ff//rsp减去0x488($0xfffffffffffffb78对应补码),可以视为预留0x488的栈空间
0x7fcfd4000014: jmpq *%rsi #* ff e6//跳转到rsi
0x7fcfd4000016: xor %eax,%eax #* 33 c0//32位的eax异或值
0x7fcfd4000018: add $0x488,%rsp #* 48 81 c4 88 04 00 00//计算好了,恢复rsp
0x7fcfd400001f: emms #* c5 f8 77//使用完MMX指令后一定要用emms指令将浮点寄存器复位
0x7fcfd4000022: pop %r15 #* 41 5f
0x7fcfd4000024: pop %r14 #* 41 5e
0x7fcfd4000026: pop %r13 #* 41 5d
0x7fcfd4000028: pop %r12 #* 41 5c
0x7fcfd400002a: pop %rbx #* 5b
0x7fcfd400002b: pop %rbp #* 5d
0x7fcfd400002c: retq #* c3
----------------
IN:
0x0000000040000000: 580000c0 ldr x0, pc+24 (addr 0x40000018)
0x0000000040000004: aa1f03e1 mov x1, xzr
0x0000000040000008: aa1f03e2 mov x2, xzr
0x000000004000000c: aa1f03e3 mov x3, xzr
0x0000000040000010: 58000084 ldr x4, pc+16 (addr 0x40000020)
0x0000000040000014: d61f0080 br x4
OP:
ld_i32 tmp0,env,$0xfffffffffffffff0
movi_i32 tmp1,$0x0
brcond_i32 tmp0,tmp1,lt,$L0//if tmp0 lt tmp1 then jmp $L0
---- 0000000040000000 0000000000000000 0000000000000f02
movi_i64 tmp2,$0x40000018
qemu_ld_i64 x0,tmp2,leq,1//使用小端序(leq)来解释内存数据。1 可能是用于指示加载行为的一个附加参数,如访问方式、对齐方式或者其他标志
---- 0000000040000004 0000000000000000 0000000000000000
movi_i64 tmp2,$0x0
mov_i64 x1,tmp2
---- 0000000040000008 0000000000000000 0000000000000000
movi_i64 tmp2,$0x0
mov_i64 x2,tmp2
---- 000000004000000c 0000000000000000 0000000000000000
movi_i64 tmp2,$0x0
mov_i64 x3,tmp2
---- 0000000040000010 0000000000000000 0000000000000f12
movi_i64 tmp2,$0x40000020
qemu_ld_i64 x4,tmp2,leq,1
---- 0000000040000014 0000000000000000 0000000000000000
mov_i64 pc,x4//翻译跳转,先保存跳转地址到pc寄存器
call lookup_tb_ptr,$0x6,$1,tmp2,env//这个是找下一个tb的,见accel/tcg/tcg-runtime.c:void *HELPER(lookup_tb_ptr)(CPUArchState *env), 如果下一个pc对应的tb存在则返回起始地址。否则返回tcg_ctx->code_gen_epilogue,它增加了返回值赋0的动作。
函数lookup_tb_ptr参数$0x6,$1,tmp2为用于存储找到pc对应的地址,env为上下文
goto_ptr tmp2//根据找到的地址跳转。goto_ptr一般前面跟着call lookup_tb_ptr查找的结果,跳转到tmp2
set_label $L0
exit_tb $0x7fcfd4000043
OUT: [size=248]
0x7fcfd4000100: mov -0x10(%rbp),%ebx #* 8b 5d f0
0x7fcfd4000103: test %ebx,%ebx #* 85 db//TEST AX,BX 与AND AX,BX命令有相同效果,只是Test指令不改变AX和BX的内容,而AND指令会把结果保存到AX中
0x7fcfd4000105: jl 0x7fcfd40001a1 #* 0f 8c 96 00 00 00//有符号小于则跳转
0x7fcfd400010b: mov $0x40000018,%ebx #* bb 18 00 00 40//
0x7fcfd4000110: mov %rbx,%rdi #* 48 8b fb//rbx为ebx的64位
0x7fcfd4000113: shr $0x7,%rdi #* 48 c1 ef 07
0x7fcfd4000117: and -0x80(%rbp),%rdi #* 48 23 7d 80
0x7fcfd400011b: add -0x78(%rbp),%rdi #* 48 03 7d 88
0x7fcfd400011f: lea 0x7(%rbx),%rsi #* 48 8d 73 07//tcg_out_modrm_offset(s, OPC_LEA + trexw, r1, addrlo, s_mask - a_mask);
0x7fcfd4000123: and $0xfffffffffffff000,%rsi #* 48 81 e6 00 f0 ff ff//tgen_arithi(s, ARITH_AND + trexw, r1, tlb_mask, 0);
0x7fcfd400012a: cmp (%rdi),%rsi #* 48 3b 37//tcg_out_modrm_offset(s, OPC_CMP_GvEv + trexw, r1, r0, which); //与tlb缓存中的地址比较?
0x7fcfd400012d: mov %rbx,%rsi #* 48 8b f3//tcg_out_mov(s, ttype, r1, addrlo);
0x7fcfd4000130: jne 0x7fcfd40001ad #* 0f 85 77 00 00 00//tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
0x7fcfd4000136: add 0x18(%rdi),%rsi #* 48 03 77 18//tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r1, r0, offsetof(CPUTLBEntry, addend));
0x7fcfd400013a: mov (%rsi),%rbx #* 48 8b 1e///* TLB Hit. */tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, -1, 0, 0, is64, opc);
0x7fcfd400013d: mov %rbx,0x40(%rbp) #* 48 89 5d 40
0x7fcfd4000141: movq $0x0,0x48(%rbp) #* 48 c7 45 48 00 00 00 00
0x7fcfd4000149: movq $0x0,0x50(%rbp) #* 48 c7 45 50 00 00 00 00
0x7fcfd4000151: movq $0x0,0x58(%rbp) #* 48 c7 45 58 00 00 00 00
0x7fcfd4000159: mov $0x40000020,%ebx #* bb 20 00 00 40
0x7fcfd400015e: mov %rbx,%rdi #* 48 8b fb
0x7fcfd4000161: shr $0x7,%rdi #* 48 c1 ef 07
0x7fcfd4000165: and -0x80(%rbp),%rdi #* 48 23 7d 80
0x7fcfd4000169: add -0x78(%rbp),%rdi #* 48 03 7d 88
0x7fcfd400016d: lea 0x7(%rbx),%rsi #* 48 8d 73 07
0x7fcfd4000171: and $0xfffffffffffff000,%rsi #* 48 81 e6 00 f0 ff ff
0x7fcfd4000178: cmp (%rdi),%rsi #* 48 3b 37
0x7fcfd400017b: mov %rbx,%rsi #* 48 8b f3
0x7fcfd400017e: jne 0x7fcfd40001ca #* 0f 85 46 00 00 00
0x7fcfd4000184: add 0x18(%rdi),%rsi #* 48 03 77 18
0x7fcfd4000188: mov (%rsi),%rbx #* 48 8b 1e
0x7fcfd400018b: mov %rbx,0x60(%rbp) #* 48 89 5d 60
0x7fcfd400018f: mov %rbx,0x140(%rbp) #* 48 89 9d 40 01 00 00
0x7fcfd4000196: mov %rbp,%rdi #* 48 8b fd
0x7fcfd4000199: callq *0x51(%rip) # 0x7fcfd40001f0 #* ff 15 51 00 00 00
0x7fcfd400019f: jmpq *%rax #* ff e0
0x7fcfd40001a1: lea -0x165(%rip),%rax # 0x7fcfd4000043 #* 48 8d 05 9b fe ff ff
0x7fcfd40001a8: jmpq 0x7fcfd4000018 #* e9 6b fe ff ff
0x7fcfd40001ad: mov %rbp,%rdi #* 48 8b fd
0x7fcfd40001b0: mov $0x31,%edx #* ba 31 00 00 00
0x7fcfd40001b5: lea -0x7f(%rip),%rcx # 0x7fcfd400013d #* 48 8d 0d 81 ff ff ff
0x7fcfd40001bc: callq *0x26(%rip) # 0x7fcfd40001e8 #* ff 15 26 00 00 00
0x7fcfd40001c2: mov %rax,%rbx #* 48 8b d8
0x7fcfd40001c5: jmpq 0x7fcfd400013d #* e9 73 ff ff ff
0x7fcfd40001ca: mov %rbp,%rdi #* 48 8b fd
0x7fcfd40001cd: mov $0x31,%edx #* ba 31 00 00 00
0x7fcfd40001d2: lea -0x4e(%rip),%rcx # 0x7fcfd400018b #* 48 8d 0d b2 ff ff ff
0x7fcfd40001d9: callq *0x9(%rip) # 0x7fcfd40001e8 #* ff 15 09 00 00 00
0x7fcfd40001df: mov %rax,%rbx #* 48 8b d8
0x7fcfd40001e2: jmpq 0x7fcfd400018b #* e9 a4 ff ff ff
0x7fcfd40001e7: nop #* 90
0x7fcfd40001e8: .quad 0x000055ebab75a2d6
0x7fcfd40001f0: .quad 0x000055ebab75af17
1681

被折叠的 条评论
为什么被折叠?



