一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - c語言中if語句是怎么變成匯編代碼的詳解

c語言中if語句是怎么變成匯編代碼的詳解

2022-03-02 14:46Just_4_fun C/C++

if語句是指編程語言,包括c語言、C#、VB、java、匯編語言等,下面這篇文章主要給大家介紹了關(guān)于c語言中if語句是怎么變成匯編代碼的相關(guān)資料,需要的朋友可以參考下

 1. 要編譯的測試代碼: 

?
1
2
3
4
5
6
7
8
9
10
int a;
int b = 3;
 
int main(void)
{
    if (3)
        a = 4;
    else
        b = 5;
}

2. 詞法分析

  詞法分析將c源代碼解析成一個(gè)個(gè)的token。

  關(guān)鍵的,將if兩個(gè)字符解析成一個(gè)if token,后續(xù)語法分析的輸入就從兩個(gè)字符減少為1個(gè)token,減小了語法分析的難度。

3. 語法分析

?
1
2
3
4
5
6
7
8
9
10
11
if (equal(tok, "if")) {
    Node *node = new_node(ND_IF, tok);
    tok = skip(tok->next, "(");
    node->cond = expr(&tok, tok);
    tok = skip(tok, ")");
    node->then = stmt(&tok, tok);
    if (equal(tok, "else"))
      node->els = stmt(&tok, tok->next);
    *rest = tok;
    return node;
  }

如果當(dāng)前處理的token是if,則

3.1 創(chuàng)建新的類型為ND_IF的node。

3.2 跳過if后面的"("。

3.3 調(diào)用expr函數(shù)解析if語句()中的表達(dá)式,并將解析結(jié)果存儲(chǔ)在node->cond。

3.4 跳過“)”。

3.5 調(diào)用stmt處理then語句塊中的語句,這里是處理"a = 4;",將解析結(jié)果存儲(chǔ)在node->then。

3.6 如果if語句還有else部分,則調(diào)用stmt處理else語句塊中的語句,這里是處理"b = 5;",將解析結(jié)果存儲(chǔ)在node->els。

3.7 node->cond,node->then,node->els都為node節(jié)點(diǎn)。

4. 代碼生成

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
switch (node->kind) {
  case ND_IF: {
    int c = count();
    gen_expr(node->cond);
    cmp_zero(node->cond->ty);
    println("  je  .L.else.%d", c);
    gen_stmt(node->then);
    println("  jmp .L.end.%d", c);
    println(".L.else.%d:", c);
    if (node->els)
      gen_stmt(node->els);
    println(".L.end.%d:", c);
    return;
  }
...

如果當(dāng)前處理的node節(jié)點(diǎn)類型為ND_IF,則

4.1 gen_expr

這個(gè)函數(shù)處理if語句的條件部分,這里是處理3。判斷node節(jié)點(diǎn)為NUM,會(huì)生成匯編語句"mov     rax, 3",將3載入rax寄存器。

4.2 cmp_zero

cmp_zero會(huì)生成匯編語句"cmp     eax, 0",比較3和0。

4.3 println(" je .L.else.%d", c);

該語句會(huì)生成匯編代碼" je .L.else.1",當(dāng)上條比較語句中eax為0時(shí)會(huì)執(zhí)行跳轉(zhuǎn),跳轉(zhuǎn)到else分支運(yùn)行。這里由于eax為3,所以不跳轉(zhuǎn)。

4.4 gen_stmt(node->then);

這條語句會(huì)將then分支中的語句解析為匯編源碼,這里是"a = 4;",這條語句是表達(dá)式語句,所以會(huì)調(diào)用gen_expr函數(shù)。

4.4.1 gen_expr

"lea     rax, a",將a的地址載入rax寄存器中。

"push rax",將rax入棧。

"mov     rax, 4",將4載入rax寄存器中。

"pop     rdi",將變量a的地址載入rdi寄存器。

"mov     [rdi], eax",將4寫入變量a。 

4.5 println(" jmp .L.end.%d", c);

執(zhí)行完then分支代碼后跳轉(zhuǎn)到下一條語句處執(zhí)行。

4.6 println(".L.else.%d:", c);

插入一條標(biāo)簽,表示else分支代碼的開始,如果if語句條件為0會(huì)跳轉(zhuǎn)到這。

4.7 gen_stmt(node->els);

生成else分支代碼,處理"b = 5;"。

"lea     rax, b",將變量b的地址載入rax寄存器。

"push    rax",將rax寄存器入棧。

"mov     rax, 5",將5載入rax寄存器。

"pop     rdi",將b的地址載入rdi寄存器。

"mov     [rdi], eax",將5寫入變量b中。

4.8 println(".L.end.%d:", c);

插入一條標(biāo)簽,表示if語句的結(jié)束,then分支語句執(zhí)行完成后跳轉(zhuǎn)到這里。

總結(jié)

到此這篇關(guān)于c語言中if語句是怎么變成匯編代碼的文章就介紹到這了,更多相關(guān)c語言if語句變成匯編代碼內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://www.cnblogs.com/iszhang/p/15592778.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品午夜久久福利大片免费 | 久久re热在线视频精69 | 亚洲国产精品高清在线 | 美女插插视频 | 九九精品国产兔费观看久久 | 欧美一级片在线免费观看 | 国产日韩欧美色视频色在线观看 | 办公室大战秘书呻吟 | 国产精品一区牛牛影视 | 亚洲日本中文字幕天堂网 | 久久九九精品国产自在现线拍 | 雪恋电影完整版免费观看 | 女子监狱第二季在线观看免费完整版 | 日韩精品一区二区三区毛片 | 门卫老张和女警花小说 | 果冻传媒天美传媒在线小视频播放 | 皇上好大好硬好涨好深好爽 | 免费国产好深啊好涨好硬视频 | 国产91精品区 | www.青草视频 | 毛毛片在线 | 高清视频在线播放ww | 亚洲区一| www.四虎在线| 狠狠撸在线影院 | 四虎地址8848aa4hc44四虎 四虎成人永久地址 | 性姿势女人嗷嗷叫图片 | h视频免费高清在线观看 | 日本久本草精品 | 精品美女国产互换人妻 | 蹭蹭妈妈的朋友小说 | 四虎影视库永久在线地址 | 女bbbbxxxx视频 | 日韩欧美中文字幕出 | 日本国产一区二区三区 | 国产91精品在线播放 | 黄a 大片a v 永久免费 | 国产欧美日韩在线观看精品 | 第一次破女视频国产一级 | 国色天香社区视频免费观看3 | 极品虎白女在线观看一线天 |