异常处理回调函数

SEH异常处理回调函数的参数定义如下:

_Handlerproc{
	_lpExceptionRecord,				//指向一个EXCEPTION_RECORD结构
	_lpSEH,							//指向EXCEPTION_REGISTRATION结构地址
	_lpContext,						//指向CONTEXT结构
	_lpDispatcherContext
}

返回值:

ExceptionContinueExcetion(等于0):回调函数返回后,系统将线程环境设置为_lpContext参数指定的CONTEXT结构并继续执行;

ExceptionContinueSearch(等于1):回调函数拒绝处理这个异常,系统将通过EXCEPIONT_REGISTRATION结构的prev字段得到前一个回调函数的地址并调用它;

ExceptionNestedException(等于2):回调函数在执行中又发生了新的异常,即嵌套异常;

ExceptionCollidedUnwind(等于3):发生了嵌套的展开操作。

CONTEXT结构成员可以改变,这意味着程序可以用改变的CONTEXT内容去执行程序,如清除断点,改变代码运行路线等。例如:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  include windows.inc 
  include user32.inc 
  include kernel32.inc 
  
  includelib user32.lib 
  includelib kernel32.lib 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>      
.data

Caption db "SEH",0
TextSEH	db "Hello,SEH!",0
Text	db "SEH程序没有运行",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   

.code

_start:
;********************************************************************
; 在堆栈中构造一个 EXCEPTION_REGISTRATION 结构
;********************************************************************
        Assume FS:NOTHING
        push  offset perThread_Handler
        push  fs:[0]       
        mov   fs:[0],esp  
;********************************************************************
; 会引发异常的指令
;********************************************************************            
	mov   esi,0
	mov   eax,[esi]	

 WouldBeOmit:                                  
        invoke  MessageBox,0,addr Text,addr Caption,MB_OK    ;这一句将无法被执行                 
;********************************************************************
; 异常处理完毕后,从这里开始执行
;******************************************************************** 
 ExecuteHere:                           
        invoke   MessageBox,0,addr TextSEH,addr Caption,MB_OK
;********************************************************************
; 恢复原来的 SEH 链
;********************************************************************
        pop     fs:[0]                      
        add     esp,4 

;********************************************************************
        invoke  ExitProcess,NULL        
;********************************************************************
; 将 EIP 指向ExecuteHere处的位置并恢复堆栈
;********************************************************************
perThread_Handler proc uses ebx pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD        

        mov     eax,pContext 
        Assume  eax:ptr CONTEXT
        lea     ebx, ExecuteHere  ; 异常后准备从ExecuteHere后开始执行
        mov     [eax].regEip,ebx  
        xor     ebx,ebx
        mov     [eax].iDr0,ebx    ; 对Drx调试寄存器清零,使断点失效(反跟踪)
        mov     [eax].iDr1,ebx
        mov     [eax].iDr2,ebx
        mov     [eax].iDr3,ebx
        mov     [eax].iDr7,341     
        mov     eax,0             ; ExceptionContinueExecution,表示已经修复
        ret                    
perThread_Handler endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end _start


下面是一段用汇编语言实现的模拟琴键的代码,使用数字键1~8模拟琴键1~1(高音),并通过PC扬声器发出相应的音调: ``` .MODEL SMALL .STACK 100H .DATA NOTE1 DB 0C9H ;音调1的频率值 NOTE2 DB 0D1H ;音调2的频率值 NOTE3 DB 0D9H ;音调3的频率值 NOTE4 DB 0E1H ;音调4的频率值 NOTE5 DB 0E9H ;音调5的频率值 NOTE6 DB 0F1H ;音调6的频率值 NOTE7 DB 0F9H ;音调7的频率值 NOTE8 DB 101H ;音调8的频率值 .CODE MAIN PROC MOV AX, @DATA MOV DS, AX ;初始化数据段寄存器 MOV DX, 61H MOV AL, 0B6H OUT DX, AL ;初始化PC扬声器控制寄存器 WAIT: IN AL, 60H CMP AL, 31H JE PLAY1 CMP AL, 32H JE PLAY2 CMP AL, 33H JE PLAY3 CMP AL, 34H JE PLAY4 CMP AL, 35H JE PLAY5 CMP AL, 36H JE PLAY6 CMP AL, 37H JE PLAY7 CMP AL, 38H JE PLAY8 JMP WAIT PLAY1: MOV AL, NOTE1 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT PLAY2: MOV AL, NOTE2 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT PLAY3: MOV AL, NOTE3 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT PLAY4: MOV AL, NOTE4 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT PLAY5: MOV AL, NOTE5 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT PLAY6: MOV AL, NOTE6 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT PLAY7: MOV AL, NOTE7 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT PLAY8: MOV AL, NOTE8 OUT 42H, AL MOV AL, AH OUT 42H, AL MOV AL, 0B6H OUT DX, AL JMP WAIT MAIN ENDP END MAIN ``` 在这段代码中,我们使用了8254芯片控制PC扬声器的工作频率,通过按下数字键1~8来选择不同的音调,同时使用了循环来不断等待键盘输入。注意,这段代码只能在实模式下运行,而且需要在DOS或类DOS操作系统下运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值