簡體   English   中英

匯編中的跳轉指令如何與多個進程一起工作?

[英]How does the jump instruction in assembly work with multiple processes?

所以,我對跳轉指令在操作系統中的工作原理感到困惑。 我認為跳轉指令設置處理器程序計數器中的值。 但程序可以在內存中的不同位置運行。 我在x86中看到,有JMP EAX指令,但我的C ++代碼似乎沒有使用它。 我在VC ++中編譯了一些C ++代碼:

int main()
{
    int i = 0;
    while (i < 10)
    {
        ++i;
        if (i == 7)
        {
            i += 1;
            continue;
        }
    }
}

這意味着:

    int main()
    {
00411370  push        ebp  
00411371  mov         ebp,esp 
00411373  sub         esp,0CCh 
00411379  push        ebx  
0041137A  push        esi  
0041137B  push        edi  
0041137C  lea         edi,[ebp-0CCh] 
00411382  mov         ecx,33h 
00411387  mov         eax,0CCCCCCCCh 
0041138C  rep stos    dword ptr es:[edi] 
        int i = 0;
0041138E  mov         dword ptr [i],0 
        while (i < 10)
00411395  cmp         dword ptr [i],0Ah 
00411399  jge         main+47h (4113B7h) 
        {
            ++i;
0041139B  mov         eax,dword ptr [i] 
0041139E  add         eax,1 
004113A1  mov         dword ptr [i],eax 
            if (i == 7)
004113A4  cmp         dword ptr [i],7 
004113A8  jne         main+45h (4113B5h) 
            {
                i += 1;
004113AA  mov         eax,dword ptr [i] 
004113AD  add         eax,1 
004113B0  mov         dword ptr [i],eax 
                continue;
004113B3  jmp         main+25h (411395h) 
            }
        }
004113B5  jmp         main+25h (411395h) 
    }
004113B7  xor         eax,eax 
004113B9  pop         edi  
004113BA  pop         esi  
004113BB  pop         ebx  
004113BC  mov         esp,ebp 
004113BE  pop         ebp  
004113BF  ret              

所以我很困惑,對於命令jmp 411395h ,這是否意味着程序總是被加載到內存中的相同位置? 因為那似乎不合邏輯。

不,這里有兩件事情可以發揮 - 你沒有指定操作系統所以我會給出一般答案。

首先,可執行文件很少采用最終格式。 作為簡化,編譯將源轉換為目標文件,並且鏈接將對象文件組合成可執行文件。

但是必須將可執行文件加載到內存中,在那個階段,可以進行更多修改。 這些修改之一可以是修復可執行文件中的內存引用以指向已在不同位置加載的內存。

這可以通過包含本身內部地址列表的可執行文件來實現,該列表需要在運行時修復。

在許多現代操作系統中,虛擬內存和物理內存之間也存在脫節。

當您的流程開始時,您將獲得自己的(用於Windows 32位的4G,我相信)加載進程的地址空間。 此地址空間中的地址與您的實際物理內存地址幾乎沒有關系,兩者之間的轉換由內存管理單元(MMU)完成。

實際上,您的進程可能會遍布物理地址空間,因為它已被分頁並進入。但虛擬地址不會改變。

正如其他人所寫的那樣,有相對跳轉和相對調用指令基本上為eip添加一個固定值,因此不依賴於程序在內存中的位置; 編譯器喜歡盡可能使用這些。 您可以查看代碼字節以查看編譯器使用的確切指令。 但是,我假設你在詢問跳轉/調用絕對地址。

當鏈接器生成可執行文件時,它會生成假定特定基址的絕對地址 ; Microsoft鏈接器通常使用400000h 當OS加載可執行文件或dll時,它通過添加實際加載可執行文件的地址與鏈接器基於它的地址之間的差異來“修復”所有絕對地址。 .com之外的所有可執行格式都指定了某種類型的修正表,其中列出了必須以這種方式修補的可執行文件中的所有位置。 因此,在OS將您的可執行文件加載到基本地址(例如1500000h ,您的跳轉將看起來像jmp 1511395h 您可以通過使用調試器查看實際代碼字節來檢查這一點。

較舊的Windows系統傾向於在鏈接器使用的基址處加載可執行文件; 這造成了安全風險,因為攻擊者會提前知道內存中的內容。 這就是為什么較新的系統使用基地址隨機化的原因。

內存位置與進程有關。 相對於程序的開頭, main始終位於內存中的相同位置。

在x86(以及其他體系結構)上,大多數跳轉指令都是IP相關的 :指令的二進制機器代碼表示與當前指令指針的偏移量。 因此,無論代碼加載到哪個虛擬地址,跳轉指令都能正常工作。

相對跳轉采用當前機器指令的地址(稱為指令指針)並添加偏移量來計算要跳轉到的地址。

如果你看看你的代碼

004113B3  jmp         main+25h (411395h) 
004113B5  jmp         main+25h (411395h) 
004113B7  xor         eax,eax 

你會注意到jmp指令長2個字節(jmp為1個字節,偏移為1個字節),並且不能存儲絕對的4字節地址。

相對跳轉是CPU的基本功能(據我所知65xx,Z80,8086,68000),與虛擬內存,內存映射或地址空間隨機化等高級功能無關。

大多數芯片具有相對跳躍(相對於當前位置)和虛擬尋址。

int main()
    {
00411370  push        ebp  
00411371  mov         ebp,esp 
00411373  sub         esp,0CCh 
00411379  push        ebx  
0041137A  push        esi  
0041137B  push        edi  
0041137C  lea         edi,[ebp-0CCh] 
00411382  mov         ecx,33h 
00411387  mov         eax,0CCCCCCCCh 
0041138C  rep stos    dword ptr es:[edi] 
        int i = 0,int j=0;
0041138E  mov         dword ptr [i][j],0
        while (i < 10)
00411395  cmp         dword ptr [i][j[,0Bh 
00411399  jge         main+47h (4113B7h) 
        {
            ++i;
0041139B  mov         eax,dword ptr [i][j] 
0041139E  add         eax,1 
004113A1  mov         dword ptr [i][j],eax '
            if (i == 7)
004113A4  cmp         dword ptr [i][j],7 
004113A8  jne         main+45h (4113B5h) 
            {
                i += 1;
004113AA  mov         eax,ebx,dword ptr [i][j] 
004113AD  add         eax,1 
004113B0  mov         dword ptr [i][j],ebx 
                continue;
004113B3  jmp         main+25h (411395h) 
            }
        }
004113B5  jmp         main+25h (411395h) 
    }
004113B7  xor         eax,ebx 
004113B9  pop         edi  
004113BA  pop         esi  
004113BB  pop         ecx  
004113BC  mov         esp,ebp 
004113BE  pop         ebp  
004113BF  ret

暫無
暫無

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

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