jerry_yang
驱动牛犊
驱动牛犊
  • 注册日期2002-10-15
  • 最后登录2005-05-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1026回复:3

这是一个嵌入bios的程序,发现当设置了自己的堆栈以后,跟读键盘16H中断就冲突了.

楼主#
更多 发布于:2004-07-22 11:11
.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
              
                
但是如果不设置自己的堆栈,或者设置了自己的堆栈而不使用键盘中断的话就很正常.
智者当借力而行
changjt
驱动牛犊
驱动牛犊
  • 注册日期2002-12-09
  • 最后登录2010-01-27
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-07-23 14:04
原因是这个样子的
因为在系统int19触发时你的代码段是处于只读的,而你这时把堆栈设在了自己的代码段,所以使的堆栈变成了只读,当然在调用int16时会有问题了,现场都没法保存了。
jerry_yang
驱动牛犊
驱动牛犊
  • 注册日期2002-10-15
  • 最后登录2005-05-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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号中断中,我调用了这个宏,改变了代码段中的数据单元,所以代码段不应该是只读的吧.
谢谢!
智者当借力而行
changjt
驱动牛犊
驱动牛犊
  • 注册日期2002-12-09
  • 最后登录2010-01-27
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-26 12:45
你这个宏肯定是执行不成功的,不信你把这些数据单元在执行后打印出来,肯定还是为0的。因为你写的是ROM程序,BIOS会把它加载到UMB里,与普通程序的最大区别就是它在int19中的只读性,这就是写ROM程序时需要注意的最大问题,所以一般写tsr都会有拷贝到内存中执行的操作。
游客

返回顶部