`
lobin
  • 浏览: 161962 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Windows下编写主引导程序到系统内核

 
阅读更多

Windows下编写主引导程序到系统内核

?

Windows下编写主引导程序、系统内核程序都比在linux平台下麻烦得多。这里给一个例子:

?

	K_CODE_SEG = 3000h
	K_CODE_OFFSET =	0000h

_text segment
	org	7c00h
_start:	
	; es, user data segment
	mov	dx, K_CODE_SEG
	mov	es, dx


	mov	ah, 02h	

	;mov	dl, 81h	; drive 0 驱动器 00H~7FH:软盘;80H~0FFH:硬盘 
	mov	dl, 00h
	;mov	dl, 0
	mov	dh, 0	; head 0 磁头
	mov	ch, 0	; track 柱面
	mov	cl, 2	; sector 扇区,读取第2个扇区

	mov	al, 10	; 指定要读取的扇区数
	mov	bx, 0	; 将指定扇区读到es:bx位置
	int	13h

	jnc	read_sector_ok
	

read_sector_error:
	mov	si, m_read_sector_error
p1:
	mov	al, [si]
	add	si, 1
	cmp	al, 00h
	je	endl
	mov	ah, 0eh
	mov	bx, 0fh
	int	10h
	jmp	p1

read_sector_ok:
	mov	si, m_read_sector_ok
p0:
	mov	al, [si]
	add	si, 1
	cmp	al, 00h
	je	jmp_to
	mov	ah, 0eh
	mov	bx, 0fh
	int	10h
	jmp	p0


jmp_to:
	mov	bx, 8
	mov	ax, es:[bx]
	mov	dx, 16
	mul	dx
	mov	cl, 4
	shr	ax, cl
	add	ax, word ptr offset_segment_jmp_to + 2
	mov	word ptr offset_segment_jmp_to + 2, ax

	; jmp	3000h:0h
	;db	0eah		; jmp far
	;dw	K_CODE_OFFSET	; offset
	;dw	K_CODE_SEG	; segment: K_CODE_SEG = 3000h


	; jmp	3000h:0h
	;db	0eah			; jmp far
	;dw	K_CODE_OFFSET, K_CODE_SEG	; offset, segment. segment: K_CODE_SEG = 3000h


	; jmp	3000h:0h
offset_segment_jmp_to:	
	dw	K_CODE_OFFSET, K_CODE_SEG

	mov	ax, cs
	cmp	ax, K_CODE_SEG
	jz	_1
	jmp	dword ptr offset_segment_jmp_to
_1:
	jmp	dword ptr offset_segment_jmp_to - 7c00h
	
endl:
	hlt
	jmp endl

m_read_sector_ok:
	db	0ah, 0ah
	db	"[ook] read sector", 0dh, 0ah
	db	0ah, 0ah
	db	00h

m_read_sector_error:
	db	0ah, 0ah
	db	"[err] read sector", 0dh, 0ah
	db	0ah, 0ah
	db	00h

	; MBR扇区位于整个硬盘的第一个扇区.
	; 硬盘扇区为512字节,所以主引导程序大小仅能也只能512字节。
	db	510-($-seg _start) dup(0)
	; MBR结束标志
	db	85, 170	; 0x55, 0xaa
_text ends
	end	_start

?

	.MODEL SMALL, C

	extrn test_09h:near

_DATA SEGMENT
	MESSAGE1 DB '[1] HELLO, INT 21H->09H!', 0DH, 0AH, '$'
_DATA ENDS

_TEXT SEGMENT
	ASSUME CS:_TEXT, DS:_DATA
	;ORG 1000H
MAIN PROC NEAR
_START:
	; DS = DS + CS
	MOV AX, _DATA
	MOV DX, CS
	ADD AX, DX
	MOV DS, AX

	MOV SI, OFFSET MESSAGE1
	
PRINT_MESSAGE:	
	MOV AL, [SI]
	CMP AL, '$'
	JE  ENDL

	MOV AH, 0EH
	MOV BX, 0FH
	INT 10H

	INC SI
	JMP PRINT_MESSAGE

	;MOV DX, OFFSET MESSAGE1	; 字符串首偏移地址放到DX中
	;MOV AH, 9
	;INT 21H			; 输出字符串

ENDL:
	CALL test_09h
	
;EXIT:
;	MOV AH, 4CH
;	INT 21H

EXIT:
	HLT
	JMP EXIT
MAIN ENDP
_TEXT ENDS
	END MAIN

?

char message[] = "Hello, MASM!\r\n$";

void test_09h() 
{
  _asm mov si, offset message;

loop: 
  _asm mov al, [si];
  _asm cmp al, '$';
  _asm je ret;

  _asm mov ah, 0eh;
  _asm mov bx, 0fh;
  _asm int 10h;

  _asm inc si;
  _asm jmp loop;
ret:

}

?

1
0
分享到:
评论
Global site tag (gtag.js) - Google Analytics 重庆时时彩怎么作弊的