监测点9.1
(1)若要使程序中的 jmp 指令执行后,CS:IP 指向程序的第一条指令,在 data 段中应该定义哪些数据?
assume cs:code
data segment
?
data ends
code segment
start:
mov ax,data
mov ds,ax ;寄存器DS指向数据段data
mov bx,0
jmp word ptr [bx+1] ;段内转移,偏移地址由[bx+1]给出
code ends
end start
解:db 3 dup(0)。(这里我犯了一个错,起初计算上了data段的padding字节大小。实际上,只需要为jmp指定cs段的ip偏移量)
(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],____
mov [bx+2],____
jmp dword ptr ds:[0]
mov ax,4c00h
int 21h
code ends
end start
解:bx, cs
dd中存储的实际就为第一指令的cs:ip。
jmp dword ptr是段间转移,高16位为段地址,低16位为段内偏移量。
故,[bx]的值为第一条指令的ip偏移量,[bx+2]的值为代码段的段号。
(3)用 Debug 查看内存,结果如下:
2000:1000 BE 00 06 00 00 00 ......
则此时,CPU 执行指令:
mov ax,2000H
mov es,ax
jmp dword ptr es:[1000H]
后,(CS)= ?,(IP)= ?
解:jmp dword ptr是段间转移,高16位为段地址,低16位为段内偏移量。cs:0006,ip:00BE
监测点9.2
补全编程,利用 jcxz 指令,实现在内存 2000H 段中查找第一个值为 0 的字节,找到后,将它的偏移地址存储在 dx 中。assume cs:code
code segment
start:
mov ax,2000H
mov ds,ax
mov bx,0
s: ________
________
________
________
jmp short s
ok: mov dx,bx
mov ax,4c00h
int 21h
code ends
end start
解:
mov ch,0 ; 这一步我觉得并没有必要,只操作cl低8位就好了,每次重新赋值不就行了
mov cl,[bx]
jcxz ok
add bx,1
监测点9.3
(1)补全编程,利用 loop 指令,实现在内存 2000H 段中查找第一个值为 0 的 byte(字节),找到后,将它的偏移地址存储在 dx 中。
assume cs:code
code segment
start:
mov ax,2000H
mov ds,ax
mov bx,0
s: mov cl,[bx]
mov ch,0
________
inc bx
loop s
ok: dec bx ;dec与inc指令的功能相反,将对应寄存器/内存单元的值减1
mov dx,bx
mov ax,4c00h
int 21h
code ends
end start
解:add cx,1(loop在cx-1后判断是否为0,故若cl为0时,需要+1后才能跳出循环)