qmeu的编译过程

本文详细介绍了qemu中的dyngen过程,包括dyngen的四个伪寄存器env, T0, T1, T2的映射,以及在不同平台上如何定义和使用operation函数。在编译过程中,op.c生成op.o,然后提取每个operation对应的host代码,通过translate.c将target instruction映射到operation函数,最终经过patch生成目标代码。" 115944601,10329531,C# Winform利用MySQL数据绘制实时曲线图教程,"['C# 开发', '数据库交互', '数据可视化', '图形界面', 'ZedGraph']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载:http://cmchao.pixnet.net/blog/post/16035915

在qmeu中,將qmeu 本身所執行的平台稱為 host,模擬的平台稱target,而將target code 轉為 host code 的過程稱為code generation。但因為qemu 是在動態執行中將target code 轉為 host code,所以多加了一個dynammic來形容。而整個過程在qemu 中稱為 dyngen。

0.9.1 版之前的dyngen 概念很簡單(但實作起來有很多細部的東東,整個就是複雜),dyegen 定義了四個pesudo register:env, T0, T1, T2,這四個register分別mapping 到 host 上真實的general register,在x86上就是 ebp, ebx, esi, edi,在x86_64上就是 r14, r15, r12, r13 (為什麼不是r12, r13, 14, 15,怪),定義在dyngen-exec.h

之後target 必需定義一些簡單的operation function,此operation function 被定義在每個  target-machine/op.c ,底下是target-arm 的例是,每個平台大同小異

,這些operation 很簡單,定義如何在pesudo register 之間搬資料,做一些簡單的動作。

void OPPROTO op_movl_T0_T1(void)
{
    T0 = T1;
}

void OPPROTO op_movl_T1_im(void)
{
    T1 = PARAM1;
}

void OPPROTO op_addl_T1_im(void)
{
    T1 += PARAM1;
}

void OPPROTO op_addl_T1_T2(void)
{
    T1 += T2;
}

void OPPROTO op_subl_T1_T2(void)
{
    T1 -= T2;
}

有了這些基本的operation後,在build qemu時會將的會將op.c 編譯成 op.o,再從op.o 將每個operation 所對應的host code抽出來,產生op.h opc.h,target-machine/translate.c 利用產生出來的個這兩個header file將每個target instruction 對應到數個operation function。就像底下的arm 例子,

        op = (insn >> 11) & 3;
        rd = (insn >> 8) & 0x7;
        if (op == 0) {
gen_op_movl_T0_im(insn & 0xff);
        } else {
gen_movl_T0_reg(s, rd);
gen_op_movl_T1_im(insn & 0xff);
        }
        switch (op) {
        case 0: /* mov */
gen_op_logic_T0_cc();
            break;
        case 1: /* cmp */
gen_op_subl_T0_T1_cc();
            break;
        case 2: /* add */
gen_op_addl_T0_T1_cc();
            break;
        case 3: /* sub */
gen_op_subl_T0_T1_cc();
            break;
        }
        if (op != 1)
gen_movl_reg_T0(s, rd);

底下是截取 objdump op.o 的部份,dyngen 會把retq 以上的部份copy 出來,再經過一些patch 就產生相對應的code 啦,上面粗體的gen_xxx_xxx的function 就會把相對應的找出來,轉換就完成啦

00000000000001e7 :
     1e7:       45 01 ec                add    %r13d,%r12d
     1ea:       c3                      retq

00000000000001eb :
     1eb:       45 29 ec                sub    %r13d,%r12d
     1ee:       c3                      retq

00000000000001ef :
     1ef:       45 01 e7                add    %r12d,%r15d
     1f2:       c3                      retq

講起來好像很簡單,那是因為假裝略過 control flow 的東東,有興趣的人自已看吧,講寫的東東其實是第二篇,先騙騙錢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值