无忧启动论坛

标题: [已解决]蛙哥进来解答下,关于汇编实现系统重启问题 [打印本页]

作者: lintel    时间: 2008-11-21 19:20
标题: [已解决]蛙哥进来解答下,关于汇编实现系统重启问题
我写了一个程序,直接使用下面的跳转代码:
jmp     F000:FFF0

编译运行后,系统却直接死机了,这个是为什么?
是不是重启前需要做什么动作?还有,我直接在实模式下的,没有在DOS环境下。

[ 本帖最后由 lintel 于 2008-11-27 22:44 编辑 ]
作者: lintel    时间: 2008-11-21 19:21
关机代码却可以实现:

mov al, 0Eh
mov dx, 0CF9h
out dx, al
jmp $
作者: netwinxp    时间: 2008-11-21 19:50
JMP FAR F000:FFF0,但所有的中断向量好像要恢复原始值,另外还要设置0040:0072~0073的值。

[ 本帖最后由 netwinxp 于 2008-11-21 20:07 编辑 ]
作者: lvyanan    时间: 2008-11-21 20:49
老猫已经作答了,是个格式问题,你那条指令在裸汇编里是可以用的,但要编译,就必须加伪指令来说明。这条绝对跳转指令,是跳转到BIOS初始化程序的入口指令,系统至此就会无条件地重新启动,不需要准备什么其它动作。

[ 本帖最后由 lvyanan 于 2008-11-22 07:29 编辑 ]
作者: lvyanan    时间: 2008-11-21 20:50
原帖由 lintel 于 2008-11-21 19:21 发表
关机代码却可以实现:

mov al, 0Eh
mov dx, 0CF9h
out dx, al
jmp $

关机代码我没接触过,见识了。
作者: netwinxp    时间: 2008-11-22 10:49
原帖由 lvyanan 于 2008-11-21 20:49 发表
老猫已经作答了,是个格式问题,你那条指令在裸汇编里是可以用的,但要编译,就必须加伪指令来说明。这条绝对跳转指令,是跳转到BIOS初始化程序的入口指令,系统至此就会无条件地重新启动,不需要准备什么其它动作。

是有区别的。在JMP FAR F000:FFF0后会检查[0040:0072]该字的值——
0000:相当于按RESET键。
1234:跳过内存检测,也就是所谓的热启动,相当于按CTRL+ALT+DEL。
5678:挂起/正常模式转换(可能对DOS无效),不检测内存、不POST、内存内容不变。
9ABC:厂家检测用。
ABCD:不停地循环POST。下面是MS给出的例程——
  1. ; Assemble options needed: none
  2. .MODEL small
  3. .CODE
  4. Start:
  5.     mov ax, @data                 ; Load ds with data segment
  6.     mov ds, ax
  7.     mov ax, 40h                   ; These three lines cause a memory
  8.     mov es, ax                    ; test NOT to be performed. To
  9.     mov WORD PTR es:[72h], 1234h  ; do a memory test, remove them.
  10.     jmp DWORD PTR b_vec           ; Jump to the reboot address
  11. .DATA
  12. b_vec   DW 00000h                 ; Offset of reboot vector
  13.         DW 0FFFFh                 ; Segment of reboot vector
  14. .STACK
  15. END Start
复制代码
以上的重启仅在实模式有效。
===============================================
想在保护模式也有效的话,可以向键盘口写"系统复位"命令(当然要在RING0下)
  1.    cli
  2.    WaitRdy: ;8042控制器忙
  3.    in al,64H ;读8042状态字节
  4.    test al,00000010B
  5.    jnz WaitRdy
  6.    mov al,0FEH ;8042 pin=0为系统复位
  7.    out 64H,al ;重启
复制代码
===============================================
其实LZ的那段代码可不一定都能实现关机,它与ACPI关机状态字节有关,根据那个字节的值的不同可能出现关机、STR、STD、唤醒、重启等多种状态。

[ 本帖最后由 netwinxp 于 2008-11-22 11:05 编辑 ]
作者: lvyanan    时间: 2008-11-22 12:31
在实模式下转入F000:FFF0后,就会开始重启过程,至于是否冷启还是热启,我觉得区别不大,系统只要重新启动即可,不必拘泥于这个细节,结果都是一样的,这样还可以省掉几条指令。
作者: netwinxp    时间: 2008-11-22 13:30
DOS下经常会在保护模式和实模式之间切换,保护模式切换成实模式有的会通过保持内存内容的系统复位来完成,也就是我们并没法保证0040:0072的内容(我所列的那几种情况并不是全部情况),也就是说如果单单是JMP F000:FFF0的话有可能会出现内存内容根本没变化的复位,这恐怕不是我们的“重启”所要的结果。
事实上,微软的重启就不是采用JMP F000:FFF0,而是采用向键盘控制器发送系统重启命令(我所列的方法二),显然酱紫可靠多了。
作者: lintel    时间: 2008-11-23 11:16
非常感谢等会我去试试
需要说明的是,这个是脱离DOS环境的,是BOOT LOADER的

[ 本帖最后由 lintel 于 2008-11-23 11:17 编辑 ]
作者: 373061200    时间: 2008-11-24 12:09
长见识了,这方面没研究那么深
作者: sgw888    时间: 2012-5-24 08:39
不好意思,挖坟了.
我是通过 jmp ffff:0000 来实现重启的.不知道有什么不同?




欢迎光临 无忧启动论坛 (http://bbs.wuyou.net/) Powered by Discuz! X3.3