增加[ds:0413H]内存大小后跳转到ES:DI失败
时间:2011-03-23
来源:互联网
BOOTORG EQU 7C00h ; our code is executed by the BIOS at 0000h:7C00h
BOOTROOT_SIZE EQU 200h
SYSRQCODE16_START EQU $
_ENTRY_POINT:
; 初始化相关寄存器及标志位
CLI ; 先关掉中断
CLD ; 方向为向前递增
XOR AX,AX ; AX = 0
MOV DS,AX ; 设置数据段寄存器 DS:SI
MOV ES,AX ; 设置附加段寄存器 ES:DI
MOV SS,AX ; 设置堆栈段寄存器
MOV BP,7C00H ; 设置基址寄存器
MOV SP,BP ; 设置堆栈栈顶
; 将MBR代码移动到0600H处
MOV SI,BP ; SI = 7C00H
MOV DI,MBR_MOVE_ADDR; DI = 0600H
MOV CX,512 ; 待移动的字节数
REP MOVSB
JMP .RealStart
; 真正开始
.RealStart:
; 保存引导驱动器号
MOV BYTE [ DriveNumber ] , DL
;
sti ;置中断允许(IF=1.当IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求.当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求)
mov AX,[ds:0413H] ;得到内存大小(0:0413H单元存有以KB计数的内存大小),这里的段地址DS应该是为0的
dec AX ;
mov [ds:0413H],AX ;将原内存大小减1K
;
;////////////////////////////// 计算高端内存地址的解释 ////////////////////////////////////////
;DOS环境下用20位来寻址,也就是说最高内存容量为 1MB=1024KB.
;AX是16位寄存器,将以KB计数的内存大小赋值在AX中,那么就只占用了AX前10位.
;段地址相当于从零开始的节数,1节是16个字节.
;左移6位的意思是把以KB为单位的内存大小变成以节为单位.
;因为1KB有64个节(1024/16=64),那么现在有AX个KB,AX*64(64为2的6次方)就计算出了总共的段数
;一个段是64k,同一个地址可以用多个[段:偏移量]来表示
;//////////////////////////////////////////////////////////////////////////////////////////
mov CL,6 ;
shl AX,CL ;计算高端内存地址
cld
mov ES,AX ;ES指向最高内存段起址,因为地址计算是以0开始,那么最末的节数就是AX-1,这里的AX就表示的是将内存减小的1KB的起始地址
mov SI,7C00h ;SI=7C00H
xor DI,DI ;DI=0
mov CX,200h ;
rep movsb ;把病毒搬移到高端地址里(DS:SI->ES:DI)
;感染后BOOT区就存放的是病毒程序,而原BOOT程序(1扇区的引导程序)被移到了2扇区
;所以系统启动后将BOOT区程序移到7C00H处,就是将病毒程序移到了那里
sti
push AX ;
mov DI, .HighAddr ;
push DI ;
retf
.HighAddr:
MOV SI,MsgLoadingOS
CALL ShowMessage
;发现没跳转到这里 请问是怎么回事
;使用近跳转可以
;mov DI, .HighAddr ;
; push DI ;
; retn;
BOOTROOT_SIZE EQU 200h
SYSRQCODE16_START EQU $
_ENTRY_POINT:
; 初始化相关寄存器及标志位
CLI ; 先关掉中断
CLD ; 方向为向前递增
XOR AX,AX ; AX = 0
MOV DS,AX ; 设置数据段寄存器 DS:SI
MOV ES,AX ; 设置附加段寄存器 ES:DI
MOV SS,AX ; 设置堆栈段寄存器
MOV BP,7C00H ; 设置基址寄存器
MOV SP,BP ; 设置堆栈栈顶
; 将MBR代码移动到0600H处
MOV SI,BP ; SI = 7C00H
MOV DI,MBR_MOVE_ADDR; DI = 0600H
MOV CX,512 ; 待移动的字节数
REP MOVSB
JMP .RealStart
; 真正开始
.RealStart:
; 保存引导驱动器号
MOV BYTE [ DriveNumber ] , DL
;
sti ;置中断允许(IF=1.当IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求.当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求)
mov AX,[ds:0413H] ;得到内存大小(0:0413H单元存有以KB计数的内存大小),这里的段地址DS应该是为0的
dec AX ;
mov [ds:0413H],AX ;将原内存大小减1K
;
;////////////////////////////// 计算高端内存地址的解释 ////////////////////////////////////////
;DOS环境下用20位来寻址,也就是说最高内存容量为 1MB=1024KB.
;AX是16位寄存器,将以KB计数的内存大小赋值在AX中,那么就只占用了AX前10位.
;段地址相当于从零开始的节数,1节是16个字节.
;左移6位的意思是把以KB为单位的内存大小变成以节为单位.
;因为1KB有64个节(1024/16=64),那么现在有AX个KB,AX*64(64为2的6次方)就计算出了总共的段数
;一个段是64k,同一个地址可以用多个[段:偏移量]来表示
;//////////////////////////////////////////////////////////////////////////////////////////
mov CL,6 ;
shl AX,CL ;计算高端内存地址
cld
mov ES,AX ;ES指向最高内存段起址,因为地址计算是以0开始,那么最末的节数就是AX-1,这里的AX就表示的是将内存减小的1KB的起始地址
mov SI,7C00h ;SI=7C00H
xor DI,DI ;DI=0
mov CX,200h ;
rep movsb ;把病毒搬移到高端地址里(DS:SI->ES:DI)
;感染后BOOT区就存放的是病毒程序,而原BOOT程序(1扇区的引导程序)被移到了2扇区
;所以系统启动后将BOOT区程序移到7C00H处,就是将病毒程序移到了那里
sti
push AX ;
mov DI, .HighAddr ;
push DI ;
retf
.HighAddr:
MOV SI,MsgLoadingOS
CALL ShowMessage
;发现没跳转到这里 请问是怎么回事
;使用近跳转可以
;mov DI, .HighAddr ;
; push DI ;
; retn;
作者: hb0012054 发布时间: 2011-03-23
如何知道“发现没跳转到这里”?CALL ShowMessage没显示出某些信息吗?这可能是你把程序重新设定到9FC0:0000之后没有设置DS造成的。:)
作者: DelphiGuy 发布时间: 2011-03-23
屏幕没有输出内容,而且我在.HighAddr:后面的代码没有运行成功,操作系统没能正常引导。假如使用
mov DI, .HighAddr ;
push DI ;
retn;
可以正常引导。
这可能是你把程序重新设定到9FC0:0000之后没有设置DS造成的。:) 请问是应该mov ds,ax吗?不好意思 汇编学的实在不怎么样。
mov DI, .HighAddr ;
push DI ;
retn;
可以正常引导。
这可能是你把程序重新设定到9FC0:0000之后没有设置DS造成的。:) 请问是应该mov ds,ax吗?不好意思 汇编学的实在不怎么样。
作者: hb0012054 发布时间: 2011-03-23
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28