逆向基礎--匯編基礎(段的分類) (07)
一.代碼段
前面了解,對于8086PC機,再編程時可以根據需要將一組內存單元定義為一個段。長度為N (N<=64kb)的一組代碼,存在一組地址連續,起始地址為16倍數的內存單元中,如果這段內存是用來存儲代碼的,被定義為一個代碼段。
mov ax,0000 ;(B8 00 00) ;初始化 AX 寄存器為 0。 如果寄存器是AX,則操作碼為B8, 后面跟著低字節00和高字節00 add ax,0123 ;(05 23 01) ;給 AX 加上 0123。 05是ADD指令家族中的一個特定操作碼,將16位立即加到AX寄存器。先23后01 mov bx,ax ;(8B D8) ;將AX復制到 BX。 jmp bx ;(FF E3) ;跳轉到內存地址 0123 處執行
上面的代碼段長度為10個字節(3,3,2,2)的機器碼,將它存放在物理地址為123B0H ~ 123B9H的一組內存單元中,就可以說這個范圍的內存是用來存放代碼的,是一個代碼段,段地址為123BH,長度為10個字節。
雖然上面代碼設置在一個代碼段內,但僅僅是編程時的一種安排,CPU并不會因為這么安排,就自動當做指令來執行。CPU只認被CS:IP指向的內存單元中的內容為指令。
所以需要將CS:IP指向123B0這個單元,也就是需要設置CS=123BH,IP=0000H。
CS中的C是Code; S是segment 指段;
CS是代碼段寄存器是存放當前在正運行的程序代碼所在段的段基址,表示當前使用的指令代碼可以從該段寄存器指定的存儲器段中取得,相應的偏移地址是則IP(指令指針寄存器)提供。
二.數據段
當我們要先保存一組數據如: 0123H, 0078H, 96FFH等一組數據。可以設置一個數據段,用來存儲這組數據,需要將DS寄存器存放數據段的段地址,當我們在使用數據的時候只需要給出偏移地址就可以了。
mov ax, 123B ;將123B(H)送入到AX寄存器 ax=123BH mov ds,ax ;將AX的值送入DS寄存器DS=123B,作為數據段的段地址(這用不能直接 mov ds,123B) mov al,[0] ;將內地址DS:0處的一個字節數據送入AL寄存器,已知AX寄存器是16位,由AH和AL組成。此命令只改變了AL(AX的低8位)的值。
下圖是一個數據段的演示,首先使用debug下的-a在內存中寫入機器指令共三條,使用 【-t 】命令來逐行調試:
1) 第一次輸入-t 會把第一行的機器指令執行。此時AX=123B , IP=0103
2) 第二次輸入-t 會把第二行的機器指令執行。此時AX=123B , DS=123B , IP=0105
3) 使用-d123B:0000命令來查看內存單元的內容,顯示第一個字節為 00
4) 第三次輸入-t會把第三行的機器指令執行。 此時AX=1200 , DS=123B , IP=0108。 我們知道第三行機器指令的 [0] 是把DS的第一個單元字節00,賦值給了AX下的AL低8位。所以由AX=AH+AL就是AX=12 +3B變成 AX=12 + 00 =1200
DS中的D是Data; S是segment 指段;
DS是數據段寄存器,指出當前程序使用的數據所存放段的最低地址,即存放數據段的段地址。他的偏移量如:[0]
三.棧段寄存器
SS中的S是stack;S是segment 指段;
指出當前堆棧的底部地址,即存放堆棧段的段基址,SS:IP指向棧頂單元
棧是一種具有特殊的訪問方式的存儲空間,在于后進先出。將元素放入棧的操作稱為入棧,從棧中取出元素的操作稱為出棧。
入棧就是將一個新的元素放到棧頂,出棧就是從棧頂取出一個元素。
棧的這種操作規則被稱為LIFO(last In First Out, 后進先出)
8086CPU同樣支持棧,相應的提供了兩個指令用于出棧以及入棧:PUSH(入棧)和POP(出棧),在編程時可以將一段內存當成棧來使用,像這樣的一段內存稱為棧段。
mov ax, 0123 push ax ;將ax的數據0123入棧,壓入到棧底 mov bx, 2266 ; push bx ;將bx的數據2266入棧,壓入到棧底 mov cx, 1122 ; push cs ;將cs的數據1122入棧,壓入到棧底 pop ax ;出棧,最后進入的是1122,所以是將1122的數據給ax pop bx ;出棧,將2266的數據給bx pop cx ;出棧,將0123的數據給cx
演示如下所示,由入棧時ax=0123,出棧時ax=2266;由入棧時bx=2266,出棧時bx=0123

上面示例中,CPU怎么知道段在哪里,又怎么知道這段空間要被當作棧來使用? 那是因為CPU有相應的寄存器標記這個棧空間,同理棧頂也有個寄存器來標記,這就是要講的SS(棧段寄存器)和SP(棧頂指針寄存器)。棧段地址存放在SS寄存器中,偏移地址存放在SP寄存器中。任意時刻SS:SP指向棧頂元素。push指令和pop指令執行時,CPU從SS和SP中得到棧頂的地址。
下圖是演示 SS:SP的地址移動關系,壓棧前SP=00FD,壓棧后SP=00FB。最后通過-d073F:00F0(SS:SP)可以看出最后SP指針指向00FB,也表示入棧成功

四.附加段數據寄存器
ES中的E是extra, S是segment 指段;
指出當前程序使用附加數據段的段基址,該段是串操作指令中,目的串所在的段。
后面在補上
浙公網安備 33010602011771號