QEMU code translate

 参考x86_64 registers-优快云博客

%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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值