实验题地址:http://www.asmedu.net/bbs/pasteinfo.jsp?part=1&level=book&kind=1010&qkSg=2&qID=70755&readSg=1
■ [mov ax,offset s]取得标号的偏移地址,ax = 标号 s 所在的那一条指令偏移地址
■ [jmp short s][jmp short 标号](转到标号处执行指令)段内短转移 功能:(ip)=(ip)+8位位移
| (对IP修改范围为-128~127)也就是说它向前转移时可以最多越过128个字节,向后转移可以最多越过127个
| 字节. "short" 符号说明指令进行的是短转移,指令中的"标号"指明了指令要转移的目的地,转移指令结束
| 后,CS:IP应该指向标号处的指令 8位位移=标号处的地址 - jmp 指令后的第一个字节的地址
|■ [jmp near ptr 标号]:段内近转移 -32768~32767 功能:(ip)=(ip)+16位位移
|■ [jmp far ptr 标号]:段间转移,又称远转移 far ptr 指明了指令用标号的段地址和偏移地址修改cs和ip
| 功能:(cs)=标号所在段的段地址 (ip)=标号在段中的偏移地址
|■ [jmp ax] IP = AX ,将 ax 的值赋值给 IP
|■ [jmp word ptr 内存单元地址(段内转移)]功能:从内存单元地址处开始存着一个字,是转移目的偏移地址
|■ [jmp dwrod ptr 内存单元地址(段间转移)]
| 功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的地址,低地址是偏移地址
■ [jcxz 标号] ■(如果(cx)=0,转移到标号处执行),当(cx)≠0时,什么也不做(程序向下执行)
■ [loop 标号] ((cx)=(cx)-1,如果(cx)≠0,转移到标号处执行)
■■ [jmp 2000:0100] 转移指令是在debug中使用的汇编指令,汇编编译器不认识,源程序中使用会报错
■■■ 80×20彩色字符模式显示缓冲区 □-B8000H~BFFFFH-□ 每行80个字符(包括颜色)占160个字节
转移指令的原理:__________ 可以修改IP,或同时修改CS和IP的指令统称为转移指令.
转移指令就是可以控制CPU执行内存中某处代码的指令.
8086CPU的转移行为有以下几类:
(1)只能修改IP时,称为段内转移,比如: jmp ax
(2)同时修改CS和IP时,称为段间转移,比如: jmp 1000:0
由于转移指令对IP的修改范围不同,段内转移又分为:□短转移和近转移
(1)短转移IP的修改范围为-128-127
(2)近转移IP的修改范围为-32768-32767
8086CPU的转移指令分为以下几类:
(1)无条件转移指令(如:jmp)
(2)条件转移指令
(3)循环指令(如:loop)
(4)过程
(5)中断
这些转移指令的转移前提条件可能不同,但基本原理相同
sp
操作符offset:__________ 由编译器处理的符号 功能:取得标号的偏移地址
assume cs:codesg
codesg segment
start: mov ax,offset start ;相当于mov ax,0
s: mov ax,offset s ;相当于mov ax,3
codesg ends
end start
以上程序中,offset操作符取得了标号start和s的偏移地址0和3,所以指令:mov ax,offset start
相当于指令mov ax,0,因为start是代码段中的标号,标记的指令是代码段中第一条指令,偏移为0
mov ax,offset s相当于指令mov ax,3因为s是代码段中的标号,标记的指令是代码段中第二条指
令,第一条指令长度为3个字节,则s的偏移地址为3
__________添写两条指令,使该程序在运行中将s处的一条指令复制到s0处
assume cs:codesg
codesg segment
s: mov ax,bx ;要复制的数据mov ax,bx长度为两个字节,即1个字
mov si,offset s ;s所处内存单元 cs:offset s
mov di,offset s0 ;s0所处内存单元 cs:offset s0
;段地址已知在CS中 偏移地址offset s 和 offset s0 已经送入 si 和 di 中
(mov ax,cs:[si]) ;将cs:offset s 处数据送入ax
(mov cs;[di],ax) ;将ax中的数据送入 cs:offset s0
s0: nop ;nop 的机器码占一个字节
nop
codesg ends
end s
jmp指令:__________ jmp为无条件转移指令,可以只修改IP,也可以同时修改CS和IP
jmp指令要给出两种信息:
(1)转移的目的地址 (2)转移的距离(段间转移\段内短转移\段内近转移)
不同的给出目的地址的方法和不同的转移位置 对应有不同格式的jmp指令
依据位移进行转移的jmp指令:__________ [jmp short s][jmp 段内短转移 标号](转到标号处指令指令)
段内短转移(对IP修改范围为-128~127)也就是说
它向前转移时可最多越过128个字节,向后转移可最多越过127个字节."short"符号说明指令进行
的是短转移,指令中的"标号"指明指令要转移的目的地,指令结束后,CS:IP应该指向标号处的指令
如: assume cs:codesg
codesg segment
start: mov ax,0
jmp short s ;越过add ax,1 IP指向标号s:处的inc ax
add ax,1
s: inc ax
codesg ends
end start ;输出结果 ax=1
[jmp short s]机器码[EB03]不包含转移的目的地址
■■ CPU在执行jmp指令的时候并不需要转移目的地址,而包含的是转移的位移,位移根据汇编指令中的
"标号"计算出来的: (ip)=(ip)+8位位移
偏移地址 机器码 汇编指令
0000 40 编译程序根据此两点的|① s: inc ax
0001 EB03 距离算出位移量:6-3=3| jmp s0
0003 BB0300 ② mov bx,3
0006 43 编译程序根据此两点的|② s0: inc bx
0007 EBF7 距离算出位移量0-9=-9| jmp s
0009 90 (补码表示为F7) ①nop
□□□ -9 的绝对值 9 的补码 0000 1001 取反加1 11110110+1=11110111B(为-9的补码)=247=F7H
(1)8位位移=标号处的地址 - jmp 指令后的第一个字节的地址
(2)short 指明此处的位移为8位位移
(3)8位位移的范围为-128~127,用补码表示0-01111111(127) 10000000-11111111(-128,-1)
(4)8位位移由编译程序在编译时算出
■■■ 段内近转移:[jmp near ptr 标号] 功能为:(ip)=(ip)+16位位移
(1)16位位移=标号处的地址 - jmp 指令后的第一个字节的地址
(2)near ptr 指明此处的位移为8位位移
(3)16位位移的范围为-32768~32767,用补码表示0-[16个1](1000000000000000为-32768)
(4)16位位移由编译程序在编译时算出
转移的目的地址在指令中的jmp指令:________ 对于当前的IP转移位移的机器指令中并没有转移的目的地址
[jmp far ptr] 功能:(cs)=标号所在段的段地址 (ip)=标号在段中的偏移地址
assume cs:codesg
codesg segment
start: mov ax,0 ;长度3
mov bx,0 ;3
jmp far ptr s ;EA0B01BD0B 高地址BD0B是转移的段地址,低位0B01是偏移
db 256 dup (0) ;7开头
s: add ax,1
inc ax
codesg ends
end start
转移地址在寄存器中的jmp指令:__________ [jmp 16位reg] 功能:(ip)=(16位reg)"Register寄存器"
[jmp ax] IP = AX ,将 ax 的值赋值给 IP
转移地址在内存中的jmp指令:__________ [jmp word ptr 内存单元地址(段内转移)]
功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址
□ 内存单元地址可用寻址方式的任意格式给出:
| mov ax,0123H mov ds:[0],ax jmp word ptr ds:[0] 执行后(ip)=0123H
| mov ax,0123H mov [bx],ax jmp wort ptr [bx] 执行后(ip)=0123H
□ [jmp dwrod ptr 内存单元地址(段间转移)]
| 功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的地址,低地址是偏移地址
| (cs)=(内存单元地址+2) (ip)=(内存单元地址)
| mov ax,0123H mov ds:[0],ax mov wort ptr ds:[2],0 jmp dword ptr ds:[0]
| 执行后,(cs)=0 (ip)=0123H cs:ip指向 0000:0123
| mov ax,0123H mov [bx],ax mov wort ptr [bx+2],0 jmp dword ptr [bx]
| 执行后,(cs)=0 (ip)=0123H cs:ip指向 0000:0123
____________________________________________________________________________________________________
(1)要使jmp指令执行后,cs:ip指向程序第一条指令,则[bx+1]处的数据必须是0
;jmp word ptr [bx+1] 修改 ip = ([bx+1]处的数据) 程序入口的地址是cs:0
;assume cs:code
;data segment
; db '0'
;data ends
;code segment
;start: mov ax,data
; mov ds,ax
; mov bx,0
; jmp word ptr [bx+1]
;code ends
;end start
_______________________________________________
(2)补全,使jmp指令后 cs:ip 指向第一条指令
;assume cs:code
;data segment
; dd 12345678H
;data ends
;code segment
;start: mov ax,data
; mov ds,ax
; mov bx,0
; mov [bx],bx ;mov [bx],? dd定义的数据占4个单元 低位地址存放偏
移地址 结果使[bx]为0
; mov [bx+2],cs ;mov [bx+2],? 高位单元存放段地址 结果
使段地址指向程序所在的段
; jmp dword ptr ds:[0]
;code ends
;end start
_______________________________________________
(3)用debug 查看内存 2000:1000 BE 00 06 00 00 00 .. .. cs=? ip=?
;mov ax,2000H
;mov es,ax
;jmp dwrod ptr es:[1000H]
;cs=6H ip=BEH
assume cs:code
code segment
mov ax,2000H
mov es,ax
jmp dword ptr es:[1000H]
code ends
end
____________________________________________________________________________________________________
jcxz指令:__________ 有条件转移指令,所有的有条件转移指令都是短转移,对应的机器码中包含转移的位移
■ 指令格式: [jcxz 标号] ■(如果(cx)=0,转移到标号处执行)
操作: 当(cx)=0时,(ip)=(ip)+8位位移
8位位移=标号处的地址-jcxz指令后的第一个字节的地址
8位位移的范围为-128~127,用补码表示
8位位移由编译程序在编译时算出
■ 当(cx)≠0时,什么也不做(程序向下执行) "jcxz 标号"的功能相当于:
C语言描述[if ((cx)==0)jmp short 标号]
____________________________________________________________________________________________________
补全编程,利用jcxz指令实现在内存2000H段中查找第一个值为0的字节,找到后将它的偏移地址存储在dx中?
assume cs:code
code segment
start: mov ax,2000h
mov ds,ax
mov bx,0
s: (mov cl,0) ;要用8位寄存器,因为如果是字型的单元数据 00 01 的话 cx≠0 跳转不了
(mov ch,[bx]) ;或写成 mov ch,0 mov cl,[bx]
(inc bx) ;本句与 jcxz ok 调转顺序没问题
(jcxz ok)
jmp short s
ok: mov dx,bx
mov ax,4c00h
int 21h
code ends
end start
____________________________________________________________________________________________________
loop指令:__________ 循环指令,所有循环指令都是短转移,机器码中包含转移的位移,IP范围:-128~127
■ 指令格式: loop 标号 ((cx)=(cx)-1,如果(cx)≠0,转移到标号处执行)
操作:(1)(cx)=(cx)-1 (2)如果(cx)≠0,(ip)=(ip)+8位位移
8位位移=标号处的地址-jcxz指令后的第一个字节的地址
8位位移的范围为-128~127,用补码表示
8位位移由编译程序在编译时算出
■ 当(cx)=0时,什么也不做(程序向下执行),"loop 标号"功能相当于:
C语言描述[(cx)--][if ((cx)≠0)jmp short 标号]
____________________________________________________________________________________________________
补全,用loop指令查找内存2000H段中第一个值为0的字节,找到后存储在dx中
assume cs:code
code segment
start: mov ax,2000h
mov ds,ax
mov bx,0
s: mov cl,[bx]
mov ch,0
inc cx
inc bx
loop s
ok: dec bx ;dec 指令的功能和inc 相反,dec bx进行的操作为;(bx)=(bx)-1
mov dx,bx
mov ax,4c00h
int 21h
code ends
end start
____________________________________________________________________________________________________
根据位移进行转移的意义:__________
对应机器码中不包含转移的目的地址,包含的是目的地址的位移 修改IP
jmp short 标号 jmp near ptr 标号 jcxz 标号 loop 标号
这种设计方便程序段在内存中的浮动装配:
mov cx,6 b9 06 00
mov ax,10h b8 10 00
s: add ax,ax 01 c0
loop s e2 fc
这段程序在内存中的不同位置都可以正确执行,因为loop s在执行时只涉及s的位移(-4,前移)
如果loop s的机器码中包含的是s的地址,如果s处的指令不在目的地址处,程序的执行就会出错
编译器对转移位移超界的检测:__________ 转移范围超界,编译时编译器将报错
编译错误:
assume cs:code
code segment
start: jmp shor s
db 128 dup (0)
s: mov ax,0ffffh
code ends
end start
jmp short s的转移范围是-128~127,ip最多向后移动127个字节
[jmp 2000:0100]转移指令是在debug中使用的汇编指令,汇编编译器不认识,源程序中使用会报错
____________________________________________________________________________________________________
实验8 这个程序可以正确返回吗? 运行后为什么是这种结果?
assume cs:codesg
codesg segment
mov ax,4c00h ;ip=0
int 21h ;ip=3
start: mov ax,0 ;ip=5 ;程序入口
s: nop ;ip=8 ;经过运行以下代码,此处机器码 90 变成 EBF6
nop ;ip=9
mov di,offset s ;ip=10 di=8H
mov si,offset s2;ip=13 si=20H
mov ax,cs:[si] ;ip=16 ax = cs:20 传送了指令[jmp short s1]的机器码EBF6 到AX
mov cs:[di],ax ;ip=19 cs:8 = ax copy了数据 EBF6 而不是指令
s0: jmp short s ;ip=22 跳转到cs:8执行 jmp short s1
s1: mov ax,0 ;ip=24
int 21h ;ip=27
mov ax,0 ;ip=29
s2: jmp short s1 ;ip=32d=20H 机器码 EBF6 ;12-22 = -10 补码 11110110B 246D F6H
nop ;ip=34
codesg ends
end start
可以正确返回,运行结果:
执行ip=16 → ax = [jmp short s1] ip=19→cs:8 = [jmp short s1] ip=22→跳转到cs:8执行
(机器码跟原来的 EBF6 ,F6H=-10B) 向后移动10个字节 ip=0 → mov ax,4c00h int 21h
____________________________________
实验9 根据材料编程 ■12行32列处输入字符串
编程:在屏幕中间分别显示绿色\绿底红色\白底蓝色的字符串'welcome to masm!'
编程所需的知识通过阅读、分析下面的材料获得.
80×25彩色字符模式显示缓冲区(简称显示缓冲区)的结构
内存空间地址中,b8000h-bFFFFh共32kb的空间,为80×25彩色字符模式的显示缓冲区,向这个地址空间写入
数据,写入的内容立即出现在屏幕上
■ 在80×25彩色字符模式下,显示器可以显示25行,每行80个字符
■ 每个字符可以有256种属性(背景色\前景色\闪烁\高亮等组合信息)
这样,一个字符在显示缓冲区中就要占两个字节,分别存放字符的ASCII码和属性
■ 80×25模式下,一屏的内容在显示缓冲区中共占4000个字节
显示缓冲区分为8页,每页4KB(≈4000B),显示器可以显示任意一页的内容,一般情况下,显示第0页的内容
通常情况下,B8000H~B8F9FH中的4000个字节的内容将出现在显示器上
在一页显示缓冲区中:
■ 偏移 000~09F 对应显示器上的第1行(80个字符占160个字节)
偏移 0A0~13F 对应显示器上的第2行
偏移 140~1DF 对应显示器上的第3行 依此类推 第25行偏移 F00~F9F
在一行中,一个字符占两个字节的存储空间(1个字),低位字节存储字符的ASCII码,高位字节存储字符属性
■ 一行共有80个字符占160个字节
即在一行中:
00~01单元对应显示器上的第1列
00~02单元对应显示器上的第2列 依此类推,9E~9F单元对应显示器上的第80列
例:在显示器的0行0列显示黑低绿色的字符串'ABCDEF'
('A'的ASCII码值为41H,02H表示黑底绿色)
显示缓冲区里的内容为:
00 01 02 03 04 05 06 07 08 09 0A 0B ... 9E 9F
B800:0000 41 02 42 02 43 02 44 02 45 02 46 02 ... ... .. .. ..
…………
B800:00A0
■ 可以看出,在显示缓冲区中,偶地址存放字符,奇地址存放字符的颜色属性
一个在屏幕上显示的字符,具有前景(字符色)和背景(字符色)两种颜色,字符还可以以高亮度和闪烁的方式
显示,前景色背景色闪烁高亮等信息被记录在属性字节中
■ 属性字节的格式(二进制): 7 6 5 4 3 2 1 0 R:红色
含义: BL R G B I E G B G:绿色
闪烁 背景 高亮 前景 B:蓝色
■ 可以按位设置属性字节,从而配出各种不同的前景色和背景色
比如:
红底绿字,属性字节为 01000010B
红底闪烁绿字 11000010B
红底高亮绿字 01001010B
黑底白字 00000111B
白底蓝字 01110001B
例:在显示器的0行0列显示红底高亮闪烁绿色的字符串'ABCDEF'
(红底高亮闪绿属性字节为:11001010B,CAH)
显示缓冲区里的内容为:
00 01 02 03 04 05 06 07 08 09 0A 0B ... 9E 9F
B800:0000 41 CA 42 CA 43 CA 44 CA 45 CA 46 CA ... .. ..
……
b800:0000 .. .. .. .. .. .. .. .. .. .. .. .. ... .. ..
■■ 闪烁的效果必须在全屏dos方式下才能看到
______________________________________________RGB=红绿蓝 000=黑色 111=白色
绿色 : 00000010 闪烁\R\G\B\高亮\R\G\B
红底绿色: 01000010
白底蓝色: 01110001
assume cs:code
data segment
db 'w e l c o m e t o m a s m ! '
data ends
code segment
start: mov ax,data
mov ds,ax
mov ax,0b800H
mov es,ax
mov cx,16
mov bx,0
s: mov al,[bx]
mov es:[bx+64].8c0H,al
mov es:[bx+64].960H,al
mov es:[bx+64].0A00H,al
mov ah,00000010B ;或2h
mov es:[bx+65].8c0H,ah
mov ah,01000010b
mov es:[bx+65].960H,ah
mov ah,01110001b
mov es:[bx+65].0A00H,ah
inc bx
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
- 实验8 这个程序可以正确返回吗? 运行后为什么是这种结果? ■■■详解
- -----------7.9------------有两种方式改变大写字母
- 第六章---------实验6.1 (1) (2)---------详细解答,,,,,,,,~~ 准确答案亲自实验.....不懂提问----------------------------------
- 实验4 --------------____________________________________----个人解释
- ■■■■■■■■■■■■■■■■■实验 10.3 结合 ■除法溢出 ■指定输出字符\颜色 ■数值显示 附□倒序
- ■■■■■■■■■■■■■■■■实验 10.1 万用子程序 (指定位置输出字符与颜色)
- 高手看一下,用本章前的所有知识怎么搞黑客帝国的数字雨效果-.-
- ■■■实验8■■■■实验9 -----------------------过程,,, 源程序测试过■■★ ★
- 实验 9. 3 ■■■ 用loo指令查找内存2000H段中第一个值为0的字节,找到后存储在dx中 ■ ■■■■详细解答
- 实验 7 --------------------准确答案,, 自己编写..经调试验证~~~~~~~~~~~~~~~~~~~~~~~~~~~~~