王爽 汇编语言个人疑问汇总第五篇
目录
第九章
实验8 分析一个奇怪的程序
原程序
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
start:
mov ax,0
s:
nop ;该指令不会产生任何的效果
nop ; 该指令不会产生任何的效果
mov di,offset s ; s标号第一条指令的地址给di
mov si,offset s2 ;s2标号第一条指令地址给si
mov ax,cs:[si] ; cs:[si] 赋值给ax寄存器
mov cs:[di],ax ; ax赋值给cs:[di]
s0:
jmp short s ; 段内短转移,转移到标号处执行指令
s1:
mov ax,0
int 21h
mov ax,0
s2:
jmp short s1 ; 段内短转移,转移到标号处执行指令
nop
codesg ends
end start
程序分析
- 我们来debug下。
- 我们输入
t
,在观察cs段寄存器
很明显看到偏移地址0008的指令变成了
JMP 0000
(nop 只占一个字节, 因此两个 nop 被完全替代)。
毫无疑问就是
mov cs:[di],ax
这段代码改变的。
还有个疑问,为什么是JMP 0000呢?
mov si,offset s2
是指向s2
代码段第一条指令的,那么应该是jmp short s1
执行s1
代码段呀。
mov cs:[di], ax
后,可以暂且认为 cs:0008现在指令是jmp short s1
机器码是EBF6
。
注意:
jmp short
是段内短转移,求的是相对位置。F6就是-10,-10
是F6
补码形式(EB代表jmp指令,F6代表了自此偏移地址开始,向前偏移10个字节),所以从0008
位置向前偏移10个字节地址是0000
。
总结
jmp short xxx
是段内短转移,注意求的是相对位置,这段代码在不同的位置效果也不一样。
实验9 根据材料编程
assume cs:code
data segment
db 'welcome to masm!'
db 01110001b ; 白底蓝字 71H
db 00100100b ; 绿底红字 24H
db 00000010b ; 黑底绿字 02H
data ends
stack segment
dw 8 dup (0)
stack ends
code segment
start: mov ax,data
mov ds,ax ; data段指向ds段寄存器
mov ax,stack
mov ss,ax ; stack段指向ss段寄存器
mov sp,16
mov ax,0b800h
mov es,ax ; 显示缓冲区指向es段寄存器
mov si,06e0h ; 字符串从哪个位置开始显示
mov cx,3 ; 循环次数
s0: mov bx,cx
mov ah,[bx+15] ; 读取行的颜色,ax寄存器的高位存颜色; 黑底绿字 02H 、 绿底红字 24H 、白底蓝字 71H
mov bx,40h ; 在一行哪个位置开始
push cx ; 外层循环暂存cx,放到栈中
mov di,0 ; 第0字节开始
mov cx,16 ; 内循环次数 16,也就是 welcome to masm! 的长度
s: mov al,[di] ; 读取字符,ax寄存器的低位存字符
mov es:[bx+si],ax ; 写入字符
inc di ; 下一个字节
add bx,2 ; 下一个字
loop s ; 内循环,显示一行的数据
add si,0a0h ; next row 下一行,作用就是换行
pop cx ; 将栈中数据弹出给cx,外层循环使用
loop s0 ; 外循环,显示下一行的数据
mov ax,4c00h
int 21h
code ends
end start
第十章
检测点10.2 下面的程序执行后,ax中的数值为多少?
mov ax,0 ;读取此条指令后IP=3
call s ;读取此条指令后IP=6 , 执行call 标号时,相当于
;push IP
;jmp near ptr 标号
; 此时将6压入栈
; 下一步转移到s段
inc ax
s: pop ax ; 取出栈中数据赋值给ax寄存器,为0006H
- 关于
mov ax,0
我们IP的值=3,参考书上2.11 修改CS、IP指令
就知道了。
检测点10.3 下面的程序执行后,ax中的数值为多少?
内存地址 机器指令 汇编指令
1000:0 b8 00 00 mov ax,0 ; 读入这条指令 IP=3
1000:3 9A 09 00 00 10 call far ptr s ; 读入这条指令 IP=8
; call far ptr 标号 时相当于
; push CS
; push IP
; jmp far ptr 标号
1000:8 40 inc ax
1000:9 50 s:pop ax ; 按照栈先入后出的特性,第一次pop取出的是IP的值,为8,传送给ax寄存器
add ax,ax ; 8H + 8H = 10H
pop bx ; 按照栈先入后出的特性,第二次pop取出的是CS的值,CS的值题目已经给出了,是1000H,传送给bx寄存器
add ax,bx ; 1000H + 10H = 1010H
AX = 1010H
- 关于
mov ax,0
我们IP的值=3,参考书上2.11 修改CS、IP指令
就知道了。
检测点10.4 下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令 执行后情况
1000:0 b8 06 00 mov ax,6 ; 读入这条指令 IP=3
1000:3 ff d0 call ax ; 读入这条指令 IP=5
; call 16位reg 相当于
;push IP ,push 5
;jmp 16位reg ,jmp 6
1000:5 40 inc ax ; 未执行
1000:6 58 mov bp,sp ; (bp) = (sp)
add ax,[bp] ;相当于add ax,[bp], bp就是sp,sp默认段地址ss,所以即把栈顶元素弹出和AX相加 ,6+5=11H
- 关于
mov ax,6
我们IP的值=3,参考书上2.11 修改CS、IP指令
就知道了。