第15章安装新的int 9的全屏闪烁程序的问题
assume cs:codestack segment
db 128 dup(0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128
push cs ;把cs的值压入栈
pop ds ;用ds来接收cs的值
mov ax,0
mov es,ax
mov si,offset int9 ;设置ds:si指向源地址
mov di,204h ;设置ds:di指向目标地址
mov cx,offset int9end - offset int9;设置cx为传输的长度
cld ;正向传输
rep movsb
;保存原int 9 程序
push es: ;原int 9偏移地址推入战中
pop es: ;用es:来保存原int 9的偏移地址
push es: ;原int 9段地址推入栈中
pop es: ;用es:来保存原int 9的段地址
;在中断向量表中设置新的int 9中断例程的入口地址
cli ;设置 if = 0 屏蔽中断
mov word ptr es:,204h ;新的int 9偏移地址放到204h中
mov word ptr es:,0 ;cs存放到段地址为0
sti ;设置if = 1 不屏蔽中断
mov ax,4c00h
int 21h
;---------新int 9中断例程----------
int9: ;把要用到的寄存器保存起来
push ax
push bx
push cx
push es
in al,60h ;把60h端口的数据传入给al中
pushf ;标志寄存器推入栈
call dword ptr cs:;当此中断执行时,(cs)=0
cmp al,3bh ;F1的键盘扫描码是3bh
jne int9ret
;全屏变颜色
mov ax,0b800h ;显存地址
mov es,ax
mov bx,1
mov cx,2000
s: inc byte ptr es:
add bx,2
loop s
int9ret:
pop ax
pop bx
pop cx
pop es
iret
int9end: nop
code ends
end start
以上是书上的源代码,想问高亮的部分为什么不能用mov word ptr es:,200h mov word ptr es:,204h来传输而是用栈来传输这个cs:ip地址? 难道是因为单纯为了保护原int 9 地址么?因为我记得在栈那一章将了,栈里的数据是不会丢失的,只不过我们理解的出栈是把取走值不在了,但是其实还是在哪里的。所以才用栈的么? 本帖最后由 xieglt 于 2020-8-12 12:12 编辑
;es:的值入栈
push es:
;将刚入栈的值弹出,保存进内存ES:
pop es:
;es:的值入栈
push es:
;将刚入栈的值弹出,保存进内存ES:
pop es:
可以改写成:
;将ES:内存的值=>AX
MOVAX,WORD PTR ES:,
;AX的值=>内存ES:
MOV WORD PTR ES:,AX
;将ES:内存的值=>AX
MOV AX,WORD PTR ES:
;AX的值=>内存ES:
MOV WORD PTR ES:,AX
你的写法是传递的立即数,而且写反了
实际上应该是
mov word ptr es:,word ptr es:
但CPU不能直接把数据从内存传到内存,必须通过寄存器中转,也就是
mov ax,word ptr es:
mov word ptr es:,ax
书上的写法是通过栈中转数据。 xieglt 发表于 2020-8-12 12:04
;es:的值入栈
push es:
;将刚入栈的值弹出,保存进内存ES:
谢谢指点我明白区别了,用栈可以少代码量并且更快一下,用mov这种方法也可行只不过由于内存根内存不能直接互传,所以需要一个寄存器介入,介于在学习8086cpu在传输过程中还是能少用寄存器就少用寄存器毕竟有限,明白了!谢谢~
页:
[1]