存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19
接著上一篇博文說。
?
5.代碼段執行時的保護
每個代碼段都有自己的段界限。同棧段一個道理,有效界限和G位相關。
G=0:有效界限 = 描述符中的段界限
G=1:有效界限 = 描述符中的段界限值 * 0x1000 + 0xFFF
當處理器取指令的時候,偏移地址由EIP提供,EIP的范圍應該在 [0,有效界限] 之間(為了說明問題,我就用數學上的閉區間表示了)。否則會引發異常。
對于本代碼,代碼段描述符中的界限值是0x1FF,G=0,那么有效界限=0x1FF,也就是說這個值就是段內最后一個允許訪問的偏移地址。
再舉一個例子,源文件中
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'及其顯示屬性這四行對應的.list文件如下
可以看到,第71行,mov dword [es:0x0b8000],0x072e0750 這條指令,其偏移地址為 0xB8~0xC2; 那么,要想這條指令順利執行,定義代碼段時,有效界限就要大于等于0xC2.當等于0xC2的時候,這條指令可以順利執行,但是下一條指令的執行會引發異常。
也就是說,如果某條指令的偏移地址為M~N,那么這條指令被順利執行的必要條件是集合[M,N]屬于集合[0,代碼段的有效界限]。(請原諒我借用集合來描述,可是我再也想不出什么簡明的表達了)
6.數據訪問時的保護
這里所說的數據段,特指向上擴展的數據段,有別于棧段和向下擴展的數據段。
訪問數據段時,是否越界與操作數的長度有關。
對于向上擴展的數據段,有效界限的計算方法依然是:
G=0:有效界限 = 描述符中的段界限
G=1:有效界限 = 描述符中的段界限值 * 0x1000 + 0xFFF
舉例來說,第74行
74 mov dword [es:0x0b800c],0x076b076f ;字符'o'、'k'及其顯示屬性這條指令的目的是把0x076b076f寫入偏移地址為0x0b800c~0x0b800f的4個存儲單元。如果要成功寫入,那么0x0b800c~0x0b800f必須在數據段的有效界限內。也就是要求:
[0xb800c, 0xb800f] 屬于 [0, 上擴數據段的有效界限]
本代碼中,數據段的有效界限值是0xFFFF_FFFF,也就是說可以訪問4GB空間內的任何一個單元。
7.使用別名段訪問代碼段對字符排序
104;------------------------------------------------------------------------------- 105 string db 's0ke4or92xap3fv8giuzjcy5l1m7hd6bnqtw.' 106;-------------------------------------------------------------------------------第105行,定義了一串字符。作者要對這串字符進行升序排序,其實“醉翁之意不在酒”——排序是假,使用別名段是真。因為代碼段是不允許寫入的,所以要修改代碼段,就需要為之創建一個別名描述符。第33、34行,程序為代碼段創建了一個可讀寫的數據段描述符。也就是說,我們可以把代碼段當成數據段來用。
33 mov dword [ebx+0x18],0x7c0001ff ;基地址為0x00007c00,512字節 34 mov dword [ebx+0x1c],0x00409200 ;粒度為1個字節,數據段描述符,可讀寫第59、60行,把這個別名段的選擇子加載到DS
59 mov eax,0x0018 60 mov ds,eax這里我們用冒泡排序法,雖然這個方法效率低,但是很適合初學者入門。關于冒泡排序的知識,請參考其他資料。
為了說明問題,我繪制了一張圖,假如一共有5個數,要把它們從左至右按照升序排列,示意圖如下。
每比較一次,就把較大的數放在右邊。那么第一次外循環后,最大的數就冒到了最右邊;第二次外循環后,第二大的數冒到了從右邊數第二個位置;……
如果N個數參加排序,那么外循環需要(N-1)次。第1次需要(N-1)次比較,第2次需要(N-2)次比較,……第(N-1)次需要一次比較。
說了這么多,我就是想說清楚代碼。
76 ;開始冒泡排序 77 mov ecx,pgdt-string-1 ;遍歷次數=串長度-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中存放的是源字的高字節 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保存著外循環的次數(字符數-1)。
79行把ECX壓棧是因為內循環也要用這個值(這個值就是本循環比較的次數),而且在內循環中,這個次數會變化。為了不破壞外循環的次數,所以要壓棧保存。
第81~89行,是內循環,完成字符對比的工作。首先一次性讀入2個字符到AX中,AL中存放的是前一個(低地址處的)字符,AH中存放的是后一個(高地址處的)字符,如果前者大,則交換AL和AH的內容,然后把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,用于顯示最終的排序結果。
第98行表示從顯存的第2行第1列(0xb8000 + 0xa0(=160D) = 0xb80a0)開始顯示字符串。當EBX=0、1、2……時,對應的地址是0xb80a0、0xb80a2、0xb80a4……(使用比例因子就是這么方便),注意,“0xb80a0 + ebx * 2”,這個表達式的值是在指令執行時,由處理器計算出來的。
?
(12章完)
總結
以上是生活随笔為你收集整理的存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gsensor 车辆碰撞算法_AEB安全
- 下一篇: 互联网日报 | 美团市值突破万亿港元;北