阅读:1026回复:3
这是一个嵌入bios的程序,发现当设置了自己的堆栈以后,跟读键盘16H中断就冲突了.
.model tiny
.386 code segment assume cs:code,ds:code saveLocale MACRO mov word ptr cs:ax_reserve,ax mov word ptr cs:bx_reserve,bx mov word ptr cs:cx_reserve,cx mov word ptr cs:dx_reserve,dx mov word ptr cs:si_reserve,si mov word ptr cs:di_reserve,di cli mov word ptr cs:ss_reserve,ss mov word ptr cs:sp_reserve,sp sti mov word ptr cs:bp_reserve,bp mov word ptr cs:ds_reserve,ds mov word ptr cs:es_reserve,es ENDM restoreLocale MACRO mov ax,word ptr cs:ax_reserve mov bx,word ptr cs:bx_reserve mov cx,word ptr cs:cx_reserve mov dx,word ptr cs:dx_reserve mov si,word ptr cs:si_reserve mov di,word ptr cs:di_reserve cli mov ss,word ptr cs:ss_reserve mov sp,word ptr cs:sp_reserve sti mov bp,word ptr cs:bp_reserve mov ds,word ptr cs:ds_reserve mov es,word ptr cs:es_reserve ENDM start: signature db 55H,0AAH comlength db 80 jmp near ptr begin0 ;the length of this instruction is 3 reserved db 20 dup(?) begin0: mov ax,cs mov ds,ax call getip ;get my program's offset in the bios module mov ax,0 mov es,ax mov ax,es:[64H] mov saveip,ax mov ax,es:[66H] mov savecs,ax mov ax,offset begin1 add ax,ipstart mov es:[64H],ax mov es:[66H],cs ;hook the 19H interrupt mov ax,0 mov si,40958 again:add ax,cs:[si] dec si jns again neg al mov checksum,al ;compute checksum mov ax,0 retf begin1: sti saveLocale mov ax,cs mov ds,ax cli mov ax,cs mov ss,ax mov sp,offset cs:stack+8192 sti ;set my own SS:SP mov ax,0 mov es,ax mov ax,saveip mov es:[64H],ax mov ax,savecs mov es:[66H],ax ;restore the original interrupt kbinput: mov ah,0 int 16H cmp ah,3BH jne kbinput ;wait for 'F1' pressed restoreLocale int 19H iret getip proc pop ax push ax sub ax,33 ;33=26(head)+3(jmp instruction)+4(two move instructions) mov ipstart,ax ret getip endp bp_static dw 0 es_static dw 0 string db 'Hello!Press F1 to continue...',00H saveip dw ? savecs dw ? ipstart dw ? ax_reserve dw 0 bx_reserve dw 0 cx_reserve dw 0 dx_reserve dw 0 si_reserve dw 0 di_reserve dw 0 ss_reserve dw 0 sp_reserve dw 0 bp_reserve dw 0 ds_reserve dw 0 es_reserve dw 0 stack db 8192 dup(0) org 40959 checksum db FCH code ends end start 但是如果不设置自己的堆栈,或者设置了自己的堆栈而不使用键盘中断的话就很正常. |
|
|
沙发#
发布于:2004-07-23 14:04
原因是这个样子的
因为在系统int19触发时你的代码段是处于只读的,而你这时把堆栈设在了自己的代码段,所以使的堆栈变成了只读,当然在调用int16时会有问题了,现场都没法保存了。 |
|
板凳#
发布于:2004-07-25 15:56
好像不是吧.
saveLocale MACRO mov word ptr cs:ax_reserve,ax mov word ptr cs:bx_reserve,bx mov word ptr cs:cx_reserve,cx mov word ptr cs:dx_reserve,dx mov word ptr cs:si_reserve,si mov word ptr cs:di_reserve,di cli mov word ptr cs:ss_reserve,ss mov word ptr cs:sp_reserve,sp sti mov word ptr cs:bp_reserve,bp mov word ptr cs:ds_reserve,ds mov word ptr cs:es_reserve,es ENDM 在19号中断中,我调用了这个宏,改变了代码段中的数据单元,所以代码段不应该是只读的吧. 谢谢! |
|
|
地板#
发布于:2004-07-26 12:45
你这个宏肯定是执行不成功的,不信你把这些数据单元在执行后打印出来,肯定还是为0的。因为你写的是ROM程序,BIOS会把它加载到UMB里,与普通程序的最大区别就是它在int19中的只读性,这就是写ROM程序时需要注意的最大问题,所以一般写tsr都会有拷贝到内存中执行的操作。
|
|