日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19

發(fā)布時間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

接著上一篇博文說。

?

5.代碼段執(zhí)行時的保護

每個代碼段都有自己的段界限。同棧段一個道理,有效界限和G位相關(guān)。

G=0:有效界限 = 描述符中的段界限

G=1:有效界限 = 描述符中的段界限值 * 0x1000 + 0xFFF

當(dāng)處理器取指令的時候,偏移地址由EIP提供,EIP的范圍應(yīng)該在 [0,有效界限] 之間(為了說明問題,我就用數(shù)學(xué)上的閉區(qū)間表示了)。否則會引發(fā)異常。

對于本代碼,代碼段描述符中的界限值是0x1FF,G=0,那么有效界限=0x1FF,也就是說這個值就是段內(nèi)最后一個允許訪問的偏移地址。

再舉一個例子,源文件中

71 mov dword [es:0x0b8000],0x072e0750 ;字符'P'、'.'及其顯示屬性 72 mov dword [es:0x0b8004],0x072e074d ;字符'M'、'.'及其顯示屬性 73 mov dword [es:0x0b8008],0x07200720 ;兩個空白字符及其顯示屬性 74 mov dword [es:0x0b800c],0x076b076f ;字符'o'、'k'及其顯示屬性

這四行對應(yīng)的.list文件如下

可以看到,第71行,mov dword [es:0x0b8000],0x072e0750 這條指令,其偏移地址為 0xB8~0xC2; 那么,要想這條指令順利執(zhí)行,定義代碼段時,有效界限就要大于等于0xC2.當(dāng)?shù)扔?xC2的時候,這條指令可以順利執(zhí)行,但是下一條指令的執(zhí)行會引發(fā)異常。

也就是說,如果某條指令的偏移地址為M~N,那么這條指令被順利執(zhí)行的必要條件是集合[M,N]屬于集合[0,代碼段的有效界限]。(請原諒我借用集合來描述,可是我再也想不出什么簡明的表達了)

6.數(shù)據(jù)訪問時的保護

這里所說的數(shù)據(jù)段,特指向上擴展的數(shù)據(jù)段,有別于棧段和向下擴展的數(shù)據(jù)段。

訪問數(shù)據(jù)段時,是否越界與操作數(shù)的長度有關(guān)。

對于向上擴展的數(shù)據(jù)段,有效界限的計算方法依然是:

G=0:有效界限 = 描述符中的段界限

G=1:有效界限 = 描述符中的段界限值 * 0x1000 + 0xFFF

舉例來說,第74行

74 mov dword [es:0x0b800c],0x076b076f ;字符'o'、'k'及其顯示屬性

這條指令的目的是把0x076b076f寫入偏移地址為0x0b800c~0x0b800f的4個存儲單元。如果要成功寫入,那么0x0b800c~0x0b800f必須在數(shù)據(jù)段的有效界限內(nèi)。也就是要求:

[0xb800c, 0xb800f] 屬于 [0, 上擴數(shù)據(jù)段的有效界限]

本代碼中,數(shù)據(jù)段的有效界限值是0xFFFF_FFFF,也就是說可以訪問4GB空間內(nèi)的任何一個單元。

7.使用別名段訪問代碼段對字符排序

104;------------------------------------------------------------------------------- 105 string db 's0ke4or92xap3fv8giuzjcy5l1m7hd6bnqtw.' 106;-------------------------------------------------------------------------------

第105行,定義了一串字符。作者要對這串字符進行升序排序,其實“醉翁之意不在酒”——排序是假,使用別名段是真。因為代碼段是不允許寫入的,所以要修改代碼段,就需要為之創(chuàng)建一個別名描述符。第33、34行,程序為代碼段創(chuàng)建了一個可讀寫的數(shù)據(jù)段描述符。也就是說,我們可以把代碼段當(dāng)成數(shù)據(jù)段來用。

33 mov dword [ebx+0x18],0x7c0001ff ;基地址為0x00007c00,512字節(jié) 34 mov dword [ebx+0x1c],0x00409200 ;粒度為1個字節(jié),數(shù)據(jù)段描述符,可讀寫

第59、60行,把這個別名段的選擇子加載到DS

59 mov eax,0x0018 60 mov ds,eax

這里我們用冒泡排序法,雖然這個方法效率低,但是很適合初學(xué)者入門。關(guān)于冒泡排序的知識,請參考其他資料。

為了說明問題,我繪制了一張圖,假如一共有5個數(shù),要把它們從左至右按照升序排列,示意圖如下。

每比較一次,就把較大的數(shù)放在右邊。那么第一次外循環(huán)后,最大的數(shù)就冒到了最右邊;第二次外循環(huán)后,第二大的數(shù)冒到了從右邊數(shù)第二個位置;……

如果N個數(shù)參加排序,那么外循環(huán)需要(N-1)次。第1次需要(N-1)次比較,第2次需要(N-2)次比較,……第(N-1)次需要一次比較。

說了這么多,我就是想說清楚代碼。

76 ;開始冒泡排序 77 mov ecx,pgdt-string-1 ;遍歷次數(shù)=串長度-1 78 @@1: 79 push ecx ;32位模式下的loop使用ecx 80 xor bx,bx ;32位模式下,偏移量可以是16位,也可以 81 @@2: ;是后面的32位 82 mov ax,[string+bx] 83 cmp ah,al ;ah中存放的是源字的高字節(jié) 84 jge @@3 85 xchg al,ah 86 mov [string+bx],ax 87 @@3: 88 inc bx 89 loop @@2 90 pop ecx 91 loop @@1

第77行,剛開始,ECX保存著外循環(huán)的次數(shù)(字符數(shù)-1)。

79行把ECX壓棧是因為內(nèi)循環(huán)也要用這個值(這個值就是本循環(huán)比較的次數(shù)),而且在內(nèi)循環(huán)中,這個次數(shù)會變化。為了不破壞外循環(huán)的次數(shù),所以要壓棧保存。

第81~89行,是內(nèi)循環(huán),完成字符對比的工作。首先一次性讀入2個字符到AX中,AL中存放的是前一個(低地址處的)字符,AH中存放的是后一個(高地址處的)字符,如果前者大,則交換AL和AH的內(nèi)容,然后把AX重寫入原來的存儲單元。接下來,BX加1,以指向下一個字符。

93 mov ecx,pgdt-string 94 xor ebx,ebx ;偏移地址是32位的情況 95 @@4: ;32位的偏移具有更大的靈活性 96 mov ah,0x07 97 mov al,[string+ebx] 98 mov [es:0xb80a0+ebx*2],ax ;演示0~4GB尋址。 99 inc ebx 100 loop @@4 101 102 hlt

排序完畢后,第93~100,用于顯示最終的排序結(jié)果。

第98行表示從顯存的第2行第1列(0xb8000 + 0xa0(=160D) = 0xb80a0)開始顯示字符串。當(dāng)EBX=0、1、2……時,對應(yīng)的地址是0xb80a0、0xb80a2、0xb80a4……(使用比例因子就是這么方便),注意,“0xb80a0 + ebx * 2”,這個表達式的值是在指令執(zhí)行時,由處理器計算出來的。

?

(12章完)

總結(jié)

以上是生活随笔為你收集整理的存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。