实验八
分析下面的程序,能否正确返回
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