實驗3 轉移指令跳轉原理及其簡單應用程式設計
阿新 • • 發佈:2021-11-23
實驗任務1
程式碼功能簡析
輸出兩行1 9 3
or 30h
是為了轉換為\(ASCII\)碼輸出。 \(30h\) 是ASCII中 \('0'\) 的編號,其二進位制形式為:\(0011 0000\) ,所以or上一個 \(30h\) 表示輸出從'0'開始偏移量為1 9 3的數字
如果 or 61h
,則輸出的是偏移量減去 \(1\) 的小寫字母。( \(61h\) 是 \(0110 0001\) ,從1開始)
$
是預定義符號,表示當前的偏移地址,使用 jmp $
,可以進入死迴圈。
問題1
反彙編檢視機器碼,可以看到其機器碼為 \(E2F2\)
\(E2\) 表示LOOP
\(F0\) 是補碼形式的位移量, \(F2\)
將其轉換為原碼 \(1!(1110010-1) = 1!(1110001) = 10001110 = -8+-4+-2=-14\)
所以其位移量為 \(-14\) 。當前ip為 \(0x19\) ,即 \(25\) ,\(25-14=11\)
但是s1處的偏移量為 \(D\) ,即 \(13\) 。
所以整個轉移的過程如下
ip指向 \(25\) 偏移處的指令,先取指令,然後ip自動 \(+2\) ,變為 \(27\) ,然後執行指令的過程中,將ip減去 \(14\) ,得到 \(13\) ,那麼下一條要執行的指令就在偏移量為 \(13\) 的地方,即s1標號處。
問題2
重複問題1的操作步驟。
\(F0\)
得到其原碼: \(1!(1110000-1) = 1!(1101111) = 10010000 = -16\)
為什麼指令數量相同,但是位移量不同?原因出在
inc
和add
的指令佔位元組數不同。8086彙編採用動態指令長度,所以每條指令的長度都不是相同的。所以這裡會有位移量的不同。CPU計算得到s2之後指令的地址方式和問題1一樣,這裡不重複描述。
實驗任務2
程式碼簡析
assume cs:code, ds:data data segment dw 200h,0h,230h,0h data ends stack segment db 16 dup(0) stack ends code segment start: mov ax,data mov ds,ax mov word ptr ds:[0],offset s1 mov word ptr ds:[2],offset s2 mov ds:[4],cs mov ax,stack mov ss,ax mov sp,16 call word ptr ds:[0] ;push ip ;jmp word ptr ds:[0] s1: pop ax ;(ax) = stack.top() = offset line23 + size(line23) = offset s1 call dword ptr ds:[2] ;push cs ;push ip ;jmp dword ptr ds:[2] s2: pop bx ;(bx) = stack.top() = offset line28 + size(line28) = offset s2 pop cx ;(bx) = stack.top() = cs = code mov ah,4ch int 21h code ends end start
問題1
(ax) = offset s1
(bx) = offset s2
(cx) = cs = code
問題2
進入debug進行驗證。
驗證AX暫存器
驗證BX暫存器
驗證CX暫存器