實驗八
分析下面的程序,能否正確返回
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
start: mov ax,0
s: nop ; nop佔一個字節
nop ; jmp short s1
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax ; 覆蓋兩個nop
s0: jmp short s
s1: mov ax,0
int 21h
mov ax,0
s2: jmp short s1 ; 機器碼 EB F6
nop
codesg ends
end start
可以正常運行並返回
該程序重點在於理解 jmp short s1,其機器碼爲EB F6,F6是位移的補碼錶示
F6 = 11110110b = 10001010(原碼) = -10 即從nop往回退10個字節
jmp short s1是基於位移的跳轉指令,所以標號s所指的指令的含義是從下一條指令的地址往回退10個字節開始執行
jmp short x不一定執行標號x所指的指令!!
第九章
編程,在屏幕中間分別顯示綠色、綠底紅色、白底藍色的字符串’welcome to masm!’
首先來確定三條語句存儲的內存地址
已知偏移000~09F對應顯示器山的第一行(160字節)
偏移0A0~13F對應顯示器第2行
……
偏移F00~F9F對應顯示器第25行
所以分別在第12、13、14行存放,其中第11行偏移從640H開始,每行之間的差爲0A0H
確定行以後再確定列
字符串共16個字節,每個字母后面跟一個字節的描述信息,共32個字節
一行80個字節,因此(160-32)/2 = 64
即每行的第65個字節開始存放
該程序使用雙重循環,外層循環每次存放一行,內層循環每次存放一行中的一個字母以及其描述信息
assume cs:code,ds:data,ss:stack
data segment
db 'welcome to masm!'
db 02H,24H,71H ; 綠 綠底紅字 白底藍字
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax
mov ax,stack ; 棧用來暫存cx
mov ss,ax
mov sp,16
mov ax,0B800H ; 目標段,注意不能以字母開頭,加0
mov es,ax
mov si,0 ; data段中第二行的偏移地址
mov di,0 ; 目標地址行的增量,每次00A0H
mov cx,3
s0: mov bx,0 ; data段中第一行的偏移地址
mov bp,0 ; 目標行中列的偏移地址
push cx
mov cx,16
s1: mov al,[bx] ; 每次循環傳送一個字母
mov es:[0+640H+di+64+bp],al
inc bp
mov al,[si+16] ; 緊跟着每個字母傳送相應的顏色
mov es:[0+640H+di+64+bp],al
inc bp ; 新的一列
inc bx ; 下一個字母
loop s1
inc si ; 下次外層循環使用新的顏色信息
add di,00A0H ; 下次外層循環需要到新的一行中存儲
pop cx
loop s0
mov ax,4c00h
int 21h
code ends
end start