簡體   English   中英

為什么向函數添加更多參數時內核會崩潰?

[英]Why does my kernel crash when I add more arguments to a function?

我正在嘗試用 C 構建一個自定義內核,我想在屏幕上放置一個彩色像素。
我已經切換到保護模式並將VGA模式設置為0x13,所以我用C編寫了一個函數,在屏幕的右上角放置一個粉紅色像素:

#include <stdint.h>

#define VGA_MODE 0x13
#define VRAM 0xA0000
#define MAX_HEIGHT 200
#define MAX_LENGTH 320

void PutPixel(uint8_t color, uint16_t x)
{
    // Return if x greater than 320
    if(x > MAX_LENGTH) return;

    unsigned char* ptr = (unsigned char*) VRAM;

    ptr += x;

    *ptr = color;

    return;
}

void KERNEL_MAIN()
{
    PutPixel(5, 320);

    return;
}

這段代碼運行得非常好,直到我想將一個 y 偏移量作為參數添加到我的 PutPixel 函數中,以便在另一行上繪制一個像素:

#include <stdint.h>

#define VGA_MODE 0x13
#define VRAM 0xA0000
#define MAX_HEIGHT 200
#define MAX_LENGTH 320

void PutPixel(uint8_t color, uint16_t x, uint16_t y)
{
    // Return if x greater than 320
    if(x > MAX_LENGTH) return;

    unsigned char* ptr = (unsigned char*) VRAM;

    ptr += x;

    *ptr = color;

    return;
}

void KERNEL_MAIN()
{
    PutPixel(5, 320, 1);

    return;
}

即使我實際上沒有使用該參數,當我在 VirtualBox 中運行代碼時,它也會立即崩潰,並且在 VirtualBox 調試器中出現以下錯誤:

dbgf event: DBGFSTOP (hyper)
File:     VINF_EM_TRIPLE_FAULT
Line:     0
Function: <NULL>
eax=000a013e ebx=00007eae ecx=00000005 edx=00000005 esi=00000000 edi=0000fff0
eip=00000083 esp=0002ffac ebp=490002ff iopl=0 nv up di pl nz na pe nc
cs=0008 ds=0010 es=0010 fs=0010 gs=0010 ss=0010               eflags=00200002
0008:00000083 f0 53                   Illegal opcode
VBoxDbg>

我可以得到一些幫助嗎?

編輯:我發現堆棧被一個字節弄亂了,所以我反匯編了函數調用,它看起來像這樣:

%0000000000007ee7 55                      push ebp
%0000000000007ee8 48                      dec eax
%0000000000007ee9 89 e5                   mov ebp, esp
%0000000000007eeb 48                      dec eax
%0000000000007eec 83 ec 10                sub esp, byte 000000010h
%0000000000007eef 89 d0                   mov eax, edx
%0000000000007ef1 44                      inc esp               ;???
%0000000000007ef2 89 c2                   mov edx, eax
%0000000000007ef4 88 4d 10                mov byte [ebp+010h], cl
%0000000000007ef7 66 89 45 18             mov word [ebp+018h], ax
%0000000000007efb 89 d0                   mov eax, edx
%0000000000007efd 66 89 45 20             mov word [ebp+020h], ax
%0000000000007f01 66 81 7d 18 40 01       cmp word [ebp+018h], word 00140h
%0000000000007f07 77 1c                   jnbe +01ch (000007f25h)
%0000000000007f09 48                      dec eax
%0000000000007f0a c7 45 f8 00 00 0a 00    mov dword [ebp-008h], 0000a0000h
%0000000000007f11 0f b7 45 18             movzx eax, [ebp+018h]
%0000000000007f15 48                      dec eax
%0000000000007f16 01 45 f8                add dword [ebp-008h], eax
%0000000000007f19 48                      dec eax
%0000000000007f1a 8b 45 f8                mov eax, dword [ebp-008h]
%0000000000007f1d 0f b6 55 10             movzx edx, byte [ebp+010h]
%0000000000007f21 88 10                   mov byte [eax], dl
%0000000000007f23 eb 01                   jmp +001h (000007f26h)
%0000000000007f25 90                      nop
%0000000000007f26 48                      dec eax
%0000000000007f27 83 c4 10                add esp, byte 000000010h
%0000000000007f2a 5d                      pop ebp
%0000000000007f2b c3                      retn

當我丟棄 0x7ef1 處的inc esp指令時, retn正確彈出返回地址,但是為什么這條指令一開始就在那里呢?

我在添加編譯器選項時找到了解決方案:

gcc -mno-red-zone

它現在完美無缺,謝謝!

暫無
暫無

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

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