汇编语言(王爽第三版)检测点13
检测点13.1
(1)在上面内容中,我们用7cH中断例程实现loop功能,则上面的7cH中断例程所能进行的最大转移位移是多少?
答案:最大转移位移是指的相对地址的偏移量,它用十进制表示比较好。
如果从loop的指令角度上看,loop就是个段内短转移,它的范围是-128~127,也就是说最大转移位移是128.
如果从例程中bx变量来说,先搞定bx存储二进制补码数据的表示范围。对于16位来说它表示的范围是(-32768~32767)。
我们知道在内存中是按照计算机补码方式存储的,最小的负数(也就是绝对值最大的数)是8000H也就是-32768,那么它最大的转移位移是32768。
注:别考虑(bx)=32768-offset s这种情况了,因为offset 是有可能是0.
有人说是FFFFH,它在内存中存储,如果表示的是数值,那么它的值是:-1
(2)用7ch中断例程完成jmp near ptr s指令功能,用bx向中断例程传送转移位移。
应用举例:在屏幕的第12行,显示data段中以0结尾的字符串。(假定源程序是zzz.asm)
assume cs:code
data segment
db 'conversation',0
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov ax,0b800h
mov es,ax
mov di,12*160
s: cmp byte ptr [si],0
je ok
mov al,[si]
mov es:[di],al
inc si
add di,2
mov bx,offset s-offset ok
int 7ch
ok: mov ax,4c00h
int 21h
code ends
end start
程序分析:
【1】此程序目的是将int 7cH指令等价于jmp near ptr s(段内近转移);位移范围是(-32768~32767),好像貌似上面的那题答案应该是32768.
【2】这里面使用了比较指令。大家多熟悉下。
【3】7cH的入口参数是bx,实现的功能是:jmp near ptr s(段内近转移);返回值:无
【4】例程代码如下:
lp: push bp ;将bp这个ss栈的偏址保存
mov bp, sp ;将当前栈顶指针值送入到bp
add [bp+2], bx ;修改ss栈中的从栈顶向下第2个单元的值
lpret: pop bp ;恢复bp值
iret ;返回到调用处。
这个没什么可说的了,都标注了。讲义中也分析了。
【5】将7cH代码写入0:200H的装载程序如下:
assume cs:code
code segment
start: ;7cH中断例程的安装程序
mov ax, cs
mov ds, ax
mov si, offset lp ;将ds:si指向源地址(captial的机器码)
mov ax, 0000H
mov es, ax
mov di, 200H ;将es:di指向目的地址(0:200H向量表中)
mov cx, offset lpend - offset lp ;设置传输长度
cld ;传输方向为正
rep movsb ;字节传输
;设置中断向量表,使7cH条目中断向量指向0000:200H
mov ax, 0000H
mov es, ax
mov word ptr es:[7cH*4], 200H
mov word ptr es:[7cH*4+2], 0000H
mov ax, 4c00H
int 21H
;-------
;装载的例程:7cH
;功能:int 7cH实现和jmp near ptr s指令相同的功能
;入口参数:bx相对地址偏移量
;返回值:无
;-------
lp: push bp ;将bp这个ss栈的偏址保存
mov bp, sp ;将当前栈顶指针值送入到bp
add [bp+2], bx ;修改ss栈中的从栈顶向下第2个单元的值
lpret: pop bp ;恢复bp值
iret ;返回到调用处。
lpend: nop ;代码段结尾,便于计算7cH例程的长度。
code ends
end start
【6】测试程序:首先将装载程序编译、连接后,执行可执行程序。
其次将zzz.asm程序编译、连接后,执行,结果是:
检测点13.2
判断下面说法的正误:
(1)我们可以编程改变FFFF:0处的指令,使得CPU不去执行BIOS中的硬件系统检测和初始化程序。
答案:错误!由于FFFF:0处的指令是无法改变的,只读的。
(2)int 19h中断例程,可以由DOS提供。
答案:错误!中断例程19h是主板上的ROM中固化的例程,是由BIOS提供的。不是由DOS提供的。