DUEL: A SUCCESSFUL DEBUG IN DOS MODE(T10-2.ASM)

调试程序:杨季文 《80X86汇编语言程序设计教程》例程T10-2.asm
平台:win xp操作系统/bochs 2.6.8/DOS 7.1中文版启动盘/winImage 9.00

构建保护模式下的汇编编译及调试环境着实费了一番功夫.
---题记

一、代码


JUMP16 MACRO selector, offsetv
	DB		0EAH
	DW		offsetv
	DW		selector
ENDM

JUMP32 MACRO selector, offsetv
	DB		0EAH
	DW		offsetv
	DW		0
	DW		selector
ENDM

DESCRIPTOR STRUC
	LIMITL		DW		0
	BASEL		DW		0
	BASEM		DB		0
	ATTRIBUTES	DW		0
	BASEH		DB		0
DESCRIPTOR	ENDS

PDESC	STRUC
	LIMIT	DW		0
	BASE	DD		0
PDESC	ENDS

ATDR = 90H
ATDW = 92H
ATDWA = 93H
ATCE = 98H
ATCE32 = 4098H
DATALEN = 16
		.386P
;-------------------------------------
DSEG SEGMENT USE16
	; ASCII_ARRAY		DB	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70
	GDT		LABEL 		BYTE
	DUMMY	DESCRIPTOR	<>
	CODE32_SEL = 08H
	CODE32	DESCRIPTOR	
   
   
    
    
	CODE16_SEL = 10H
	CODE16	DESCRIPTOR	<0FFFFH, , , ATCE, >
	; CODE_SEL = CODE - GDT
	DATAS_SEL = 18h
	DATAS	DESCRIPTOR	
    
    
     
     
	; DATAS_SEL = DATAS - GDT
	DATAD_SEL = 20H
	DATAD   DESCRIPTOR	
     
     
      
      
	; DATAD_SEL = DATAD - GDT
	STACKS_SEL = 28H
	STACKS 	DESCRIPTOR	<0FFFFH, , , ATDWA, >
	NORMAL_SEL = 30H
	NORMAL 	DESCRIPTOR	<0FFFFH, 0, 0, ATDW, 0>
	GDTLEN = $ - GDT
	; 
	VGDTR 	PDESC	
      
      
       
       
	; 
	VARSS	DW		?
	; BUFFERLEN 	= 256
	; BUFFER		DB BUFFERLEN DUP (0)
DSEG	ENDS
	;------------------------------------
CSEG1 SEGMENT USE16		'REAL'
		ASSUME CS: CSEG1, DS: DSEG
	START: 
		jmpseg   equ   40h      ;打算修改的段
		mov      ax,jmpseg
		mov    ds,ax               ;ds=打算修改的段
		xor       si,si
		mov       ax,ds:[si]            ;修改 ds:0 的位置
		push       ax               ;安全起见,在堆栈保存这个位置的值
		mov      byte ptr ds:[si],0cbh      ;将这个位置设置为 retf
		push      cs
		push      offset    back            ;设置返回位置
		db      0eah               ;远跳转
		dw      0
		dw      jmpseg
		back:                  ;跳过去后马上回来
		pop      ax
		mov      ds:[si],ax            ;再恢复下面就是继续执行了

		MOV AX, DSEG
		MOV DS, AX
		
		;XCHG BX, BX
		
		MOV BX, 16
		MUL BX
		ADD AX, OFFSET GDT
		ADC DX, 0
		MOV WORD PTR VGDTR.BASE, AX
		MOV WORD PTR VGDTR.BASE + 2, DX
		
		MOV AX, CSEG2
		MUL BX
		MOV CODE32.BASEL, AX
		MOV CODE32.BASEM, DL
		MOV CODE32.BASEH, DH
		
		MOV AX, CSEG3
		MUL BX
		;ADD AX, OFFSET BUFFER
		;ADC DX, 0
		MOV CODE16.BASEL, AX
		MOV CODE16.BASEM, DL
		MOV CODE16.BASEH, DH
		
		MOV AX, SS
		MUL BX
		;ADD AX, OFFSET BUFFER
		;ADC DX, 0
		MOV STACKS.BASEL, AX
		MOV STACKS.BASEM, DL
		MOV STACKS.BASEH, DH
		MOV VARSS, SS
		
		LGDT FWORD PTR VGDTR
		; 
		CLI
		CALL EA20
		
		MOV EAX, CR0
		OR  EAX, 1
		MOV CR0, EAX
		
		; JUMP16 
       
       
         , 
        
          JUMP16 
         
           , 
          
            ; TOREAL: MOV AX, DSEG MOV DS, AX MOV SS, VARSS CALL DA20 STI MOV AH, 4CH INT 21H ; JMP $; poor style. EA20 PROC PUSH AX IN AL, 92H OR AL, 2 OUT 92H, AL POP AX RET EA20 ENDP ; DA20 PROC PUSH AX IN AL, 92H AND AL, 0FDH OUT 92H, AL POP AX RET DA20 ENDP ; CSEG1 ENDS CSEG2 SEGMENT USE32 'PM32' ASSUME CS: CSEG2 SPM32: MOV AX, STACKS_SEL MOV SS, AX MOV AX, DATAS_SEL MOV DS, AX MOV AX, DATAD_SEL MOV ES, AX ; XOR ESI, ESI XOR EDI, EDI MOV ECX, DATALEN CLD NEXT: LODSB PUSH AX CALL TOASCII MOV AH, 01000010B SHL EAX, 16 POP AX SHR AL, 4 CALL TOASCII MOV AH, 01000010B STOSD MOV AL, ' ' STOSW LOOP NEXT ; JUMP32 CODE16_SEL, 
           
             ; TOASCII PROC ; PUSH SI ; AND AL, 00001111B ; MOV SI, AX ; MOV AL, ASCII_ARRAY[SI] ; POP SI AND AL, 0FH ADD AL, 90H DAA ADC AL, 40H DAA RET TOASCII ENDP ; CODE32LEN = $ CODE32SIG: NOP CSEG2 ENDS CSEG3 SEGMENT USE16 'PM16' ASSUME CS: CSEG3 CODE32LEN = OFFSET CODE32SIG OFFSET_SPM32 = OFFSET SPM32 SPM16: XOR SI, SI MOV DI, DATALEN * 3 * 2 MOV AH, 7 MOV CX, DATALEN AGAIN: LODSB STOSW LOOP AGAIN ; MOV AX, NORMAL_SEL MOV DS, AX MOV ES, AX AND EAX, 0FFFFFFFFH MOV CR0, EAX JMP FAR PTR TOREAL CSEG3 ENDS END START 
            
           
          
         
       
      
      
     
     
    
    
   
   

二、说明
1. offset伪指令依赖于编译环境
16位环境下,采用段:偏移的分段方式管理内存,offset返回dw(单字)段内偏移值;而32位下,offset返回内存绝对地址,即dd(双字)。处理方式为将源代码中offset语句从32位段移至16位段(可用NOP标记)。
2. 编译环境的配置
Microsoft Macro Assembler Version 9.00.21022.08
Microsoft Segmented Executable Linker Version 5.60.339
汇编程序严格依赖编译环境,编译环境是程序可重复性的保证。ml.exe从VS2008/VC/bin 中提取,link.exe取自masm 6.0. masm 6.0 之前的版本不支持32位汇编(如不能准确编译lgdt操作码),其后的版本中直到masm 9.0 才对保护模式汇编稳定支持。
参考 博文 《如何编写引导程序 Hello World》
3. 调试环境的配置
参考 博文《用bochs调试保护模式程序》
三、效果截图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值