早期的BIOS如何使用CALL? [英] How can early BIOS use CALL?

查看:154
本文介绍了早期的BIOS如何使用CALL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我纯粹出于业余爱好,试图理解PC中的一些底层代码.我为随机的旧千兆字节MB下载了过时的BIOS ROM映像( https://www.gigabyte.com/Motherboard/GA-8I845GE775-G-rev-10/support#support-dl-bios ),它已经15岁了,所以我希望不会损害任何人的知识产权.我将使用此文件作为参考.

I am, purely for hobby reasons, trying to understand some low-level code in the PC. I downloaded an outdated BIOS ROM image for a random old Gigabyte MB (https://www.gigabyte.com/Motherboard/GA-8I845GE775-G-rev-10/support#support-dl-bios), it's almost 15 years old so I hope it doesn't harm anyone's IP rights. I'll be using this file for reference.

我一开始就迷迷糊糊了.这些似乎是处理器在加电后首先看到的指令:

I'm stumbled right at the beginning. These seem to be the very first instructions the processor sees after power up:

f000:fff0  ljmp 0xf000:0xe05b
f000:e05b  jmp 0xf46c
f000:f46c  cli
f000:f46d  cld
f000:f470  smsw ax       ; read CR0
f000:f473  test al, 1    ; test Protected Mode Enable
f000:f475  je 0xf480
[assuming PE is zero – jump:]
f000:f480  jmp 0xe043
f000:e043  mov al, 0x8f
f000:e045  out 0x70, al  ; CMOS controller: disable NMI, set index 0xf
f000:e047  out 0xeb, al  ; this port is presumably unoccupied: just a delay mechanism
f000:e049  in al, 0x71   ; read 0xf (CMOS Shutdown Status)
f000:e04b  out 0xeb, al  ; more delay
f000:e04d  or al, al
f000:e04f  jmp 0xf483
f000:f483  jne 0xf488
[assuming status = 0 (Power on or soft reset) – pass:]
f000:f485  call 0x4dee

假定在打开计算机电源后CMOS关机状态为零,BIOS会在f000:f485发出呼叫.在那早的时刻,不会尝试检测是否存在任何RAM.堆栈段和堆栈指针也未设置. f000:f485处的代码确实看起来像一个函数,并以ret结尾. call在哪里将返回地址存储在哪里?

Assuming the CMOS shutdown status is zero upon powering the computer on, the BIOS issues a call at f000:f485. At that early moment, no attempt would have been done at detecting whether any RAM is even present. The stack segment and stack pointer have not been set up, either. The code at f000:f485 indeed looks like a function and ends with a ret. How is this possible, where does the call store the return address?

还是我误解了从端口0x71返回的值?我将这两个文档用作参考:

Or am I misunderstanding the values returned from port 0x71? I used these two documents for reference:

0x8f写入0x70的含义: https://wiki.osdev.org/CMOS#CMOS_寄存器

随后从0x71中读取值的含义: http://www.bioscentral .com/misc/cmosmap.htm

The meaning of the values subsequently read from 0x71: http://www.bioscentral.com/misc/cmosmap.htm

推荐答案

有2种情况:

a)冷启动"(例如,当计算机未运行且您将其打开时).在这种情况下;内存控制器不会被初始化,关机状态也不会被设置,jne 0xf488会导致代码跳到其他地方,并且call不会被执行.

a) "cold boot" (e.g. when the computer wasn't running and you turn it on). In this case; the memory controllers won't be initialized, the shutdown status won't be set, the jne 0xf488 will cause the code to jump somewhere else, and the call won't be executed.

b)热启动"(例如,在计算机已经运行后重置计算机时).在这种情况下;内存控制器仍处于初始化状态(从先前的冷启动"开始),将设置关闭状态,jne 0xf488将不执行任何操作,并且将执行call(但这很好,因为内存控制器被初始化).

b) "warm boot" (e.g. when you reset the computer after it's already running). In this case; the memory controllers are still initialized (from when "cold boot" happened previously), shutdown status will be set, the jne 0xf488 won't do anything, and the call will be executed (but that's fine, because the memory controllers are initialized).

假设计算机开机后CMOS关机状态为零...

Assuming the CMOS shutdown status is zero upon powering the computer on...

不.关闭状态字节值是(根据Ralph Brown的中断列表):

No. The shutdown status byte values are (according to Ralph Brown's Interrupt List):

  • 0x00 =软件重置或意外重置
  • 0x01 =在虚拟模式下检查内存大小后重置
  • 0x02 =在实模式/虚拟模式下成功进行内存测试后重置
  • 0x03 =在真实/虚拟模式下内存测试失败后重置
  • 0x04 = INT 0x19重新启动
  • 0x05 =刷新键盘并跳过. 0x0040:0x0067
  • 0x06 =重置(在虚拟模式下成功测试之后)
  • 0x07 =重置(在虚拟模式下失败测试之后)
  • 0x08 =受保护的模式RAM测试期间由POST使用
  • 0x09 =用于INT 0x15/0x87(块移动)支持
  • 0x0A =通过JMP通过恢复执行. 0x0040:0x0067
  • 0x0B =通过IRET恢复执行. 0x0040:0x0067
  • 0x0C =通过RETF通过恢复执行. 0x0040:0x0067
  • 0x0D到0xFF =执行上电复位(冷启动")
  • 0x00 = software reset or unexpected reset
  • 0x01 = reset after memory size check in virtual mode
  • 0x02 = reset after successful memory test in real/virtual mode
  • 0x03 = reset after failed memory test in real/virtual mode
  • 0x04 = INT 0x19 reboot
  • 0x05 = flush keyboard and jump via. 0x0040:0x0067
  • 0x06 = reset (after successful test in virtual mode)
  • 0x07 = reset (after failed test in virtual mode)
  • 0x08 = used by POST during protected=mode RAM test
  • 0x09 = used for INT 0x15/0x87 (block move) support
  • 0x0A = resume execution by JMP via. 0x0040:0x0067
  • 0x0B = resume execution by IRET via. 0x0040:0x0067
  • 0x0C = resume execution by RETF via. 0x0040:0x0067
  • 0x0D to 0xFF = perform power-on reset ("cold boot")

注意:拉尔夫·布朗(Ralph Brown)的中断列表没有被保存很久了.我希望其中一些是旧的,并且/或者仅适用于一些非常旧的计算机(例如80286,除了重置之外,它没有其他方法可以退出保护模式).

Note: Ralph Brown's Interrupt List hasn't been maintained for ages. I'd expect some of this is old and/or only applies to some very old computers (e.g. 80286, which didn't have any way to leave protect mode other than reset).

这篇关于早期的BIOS如何使用CALL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆