簡體   English   中英

為什么中斷不是由 C 代碼生成,而是由匯編指令容易生成?

[英]Why Interrupts not generates by C code but easy generates by assembly instructions?

我正在編程一點 kernel,並實現 idt 和中斷。

我的小 kernel 中的這個 C 代碼不會產生任何中斷:

int x = 5/0;

int f[4];
f[5] = 8;   

但是這個匯編代碼可以產生任何中斷:

asm("int $0");

(並且處理程序工作正常)。

幫助我理解為什么會發生這種情況。

我也試過這個:

    int a = 3;
    int b = 3;  
    int c = a-b;
    int x = a/c;

我在 c 代碼中嘗試的任何操作都不會為我生成異常。

即使這樣也沒有用:

int div_by_0(int a, int b){return a/b;}

int x = div_by_0(5, 0);
void fun ( void )
{
    int a = 3;
    int b = 3;
    int c = a-b;
    int x = a/c;
}

Disassembly of section .text:

0000000000000000 <fun>:
   0:   f3 c3                   repz retq 

沒有除以觸發除以零。 都是死代碼。

這些都與 int 指令無關,這些是完全獨立的主題。

如評論中所述,在不使用死代碼的情況下對其進行測試。

int fun0 ( int x )
{
    return(5/x);
}
int fun1 ( void )
{
    return(fun0(0));
}

但要明白它仍然可能沒有達到預期的效果:

Disassembly of section .text:

0000000000000000 <fun0>:
   0:   b8 05 00 00 00          mov    $0x5,%eax
   5:   99                      cltd   
   6:   f7 ff                   idiv   %edi
   8:   c3                      retq   
   9:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000000010 <fun1>:
  10:   0f 0b                   ud2 

因為 fun1 的優化器可以看到 fun0 function。 您希望在單獨的優化域中測試代碼。 在上面的這種情況下,idiv 將生成除以零。 然后它就變成了一個操作系統問題,即如何處理以及它是否對您可見。

您看到的問題是因為除以 0 是C/C++中未定義的行為。 編譯器已經設法在編譯時進行了足夠的優化,以實現您被零除。 編譯器可以自由地做任何事情,從停止和着火到使結果為 0。一些編譯器會發出ud2指令來引發 CPU 異常。 結果未定義。

你有幾個選擇。 在匯編中編寫您的部門並從C/C++調用 function 。 由於您使用的是 GCC (也適用於 CLANG)您還可以使用內聯匯編生成除以零,如下所示:

#include <stdint.h>  /* or replace uint16_t with unsigned short int */ 

void div_by_0 (void)
{
    asm ("div %b0" :: "a"((uint16_t)0));
    return;
}

這會將AX設置為 0,然后使用DIV指令將AX除以AL 0/0 未定義,將引發除法異常 (#DE)。 此內聯匯編應適用於 16、32 和 64 位代碼。


在保護模式或長模式下,使用int $# (其中#是向量編號)觸發異常並不總是與獲取 CPU 生成的異常相同。 CPU 產生的一些異常會在返回地址之后將錯誤代碼推送到堆棧上,該錯誤代碼需要由中斷處理程序清理。 如果您使用來自 ring 0 的int $0x0d來導致 #GP 異常,則中斷處理程序可能會在從中斷返回時出錯,因為使用int生成異常永遠不會在堆棧上放置錯誤代碼。 這不是int $0的問題,因為 #DE 沒有 CPU 將錯誤代碼放在堆棧上。

原來是由於優化標志。 由於 Makefiles 有點混亂, -O2 標志起作用了。 如果啟用 -O0 標志,異常會直接從 C 運行。 甚至這個簡單的代碼也會引發異常:

int x = 5/0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM