Я пишу простую программу на ассемблере (NASM). Когда загрузочный сектор загружается, он должен отображать всю память (RAM), установленную на компьютере, в мегабайтах. При загрузке загрузочного сектора операционной системы (DOS, Windows, Linux) не будет, так как узнать общий объем ОЗУ? У меня 2 ГБ оперативной памяти на моем компьютере. Я много искал в Интернете, но не смог найти решение.
Есть ли прерывание BIOS, которое показывает объем памяти 2 ГБ? Существует прерывание, которое использовалось на старых компьютерах для отображения памяти, но не все 2 ГБ. Я проверил, и нет никакого решения для этого в списке Ральфа Брауна. Может быть, кто-то знает больше о BIOS. Если BIOS не предоставляет эту возможность, могу ли я использовать C / C ++ для определения общего объема оперативной памяти? И вызывать C / C ++ код из сборки? Какая функция C / C ++ будет использоваться для определения общего объема оперативной памяти?
Помните, что мой ассемблерный код будет выполнять холодную загрузку, и не будет никакой операционной системы, которая бы обеспечивала мой код каким-либо средством.
Редакция:
Я читаю сайт http://wiki.osdev.org/Detecting_Memory_%28×86%29. И решил проверить, работает ли int 15. Поэтому я получил код с этого сайта и отредактировал его, чтобы проверить, работает ли int 15 EAX = E820. Но он не работает, и вывод «F» в .failed1. «F» — это тестовый пример, который я сделал для проверки «неподдерживаемой функции». Тестовые случаи: «F», «G» и «H». Вот код
; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
; inputs: es:di -> destination buffer for 24 byte entries
; outputs: bp = entry count, trashes all registers except esi
do_e820:
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 0x15
jc short .failed1 ; carry set on first call means "unsupported function"mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"jne short .failed2
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je short .failed3
jmp short .jmpin
.e820lp:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc short .e820f ; carry set means "end of list already reached"mov edx, 0x0534D4150 ; repair potentially trashed register
.jmpin:
jcxz .skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe short .notext
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
je short .skipent
.notext:
mov ecx, [es:di + 8] ; get lower dword of memory region length
or ecx, [es:di + 12] ; "or" it with upper dword to test for zero
jz .skipent ; if length qword is 0, skip entry
inc bp ; got a good entry: ++count, move to next storage spot
add di, 24
.skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne short .e820lp
.e820f:
mov [mmap_ent], bp ; store the entry count
clc ; there is "jc" on end of list to this point, so the carry must be cleared
mov ah, 0x0E ; Teletype command
mov bh, 0x00 ; Page number
mov bl, 0x07 ; Attributes (7 == white foreground, black background)
mov al, mmap_ent ; Character to print
int 0x10
ret
.failed1:
push eax
push ebx
mov ah, 0x0E ; Teletype command
mov bh, 0x00 ; Page number
mov bl, 0x07 ; Attributes (7 == white foreground, black background)
mov al, 70 ; Character 'F' to print
int 0x10
pop ebx
pop eax
stc ; "function unsupported" error exit
ret
.failed2:
push eax
push ebx
mov ah, 0x0E ; Teletype command
mov bh, 0x00 ; Page number
mov bl, 0x07 ; Attributes (7 == white foreground, black background)
mov al, 71 ; Character 'G' to print
int 0x10
pop ebx
pop eax
stc ; "function unsupported" error exit
ret
.failed3:
push eax
push ebx
mov ah, 0x0E ; Teletype command
mov bh, 0x00 ; Page number
mov bl, 0x07 ; Attributes (7 == white foreground, black background)
mov al, 72 ; Character 'H' to print
int 0x10
pop ebx
pop eax
stc ; "function unsupported" error exit
retmmap_ent db 0
failmsg db 0
failmem db 'Failed', 0
;times 512-($-$$) db 0
;dw 0xAA55
Редакция:
Я использовал nasm memext.asm -o memext.com -l memext.lst. Использовал MagicISO для создания загрузочного образа файла memext.iso, а для записи на DVD / RW — на устройство записи дисков Windows. Загрузил Oracle VM и создал новую виртуальную машину с 256 МБ ОЗУ, CD / DVD, жестким диском объемом 2 ГБ. Загрузился с DVD для теста холодной загрузки, ничего не печатает.
Кроме того, я открываю командную консоль и просто набираю memext, и в качестве результата она выдает «F».
Вам нужно будет прочитать таблицы ACPI на ПК (или на других компьютерах, поддерживающих ACPI).
Обратите внимание, что это не даст вам общий размер в виде одного числа, но даст вам объем памяти каждой области памяти — на простой машине, которая может быть просто двумя или тремя областями (в «дыре» нет места 0xA0000-0xFFFFF и везде, где BIOS решает поставить «PCI-дыру»).
Я подозреваю, что не совсем просто встроить считыватель ACPI в один сектор, учитывая, что у некоторого загрузочного сектора есть только около 400 байт доступного пространства (хотя, если вы полностью пропустите таблицу разделов, я предполагаю, что вы можете использовать почти все из 512 байт).
Что касается «как вызывать C / C ++», вы не сможете разместить какую-либо значимую программу на C или C ++ менее чем в нескольких секторах. Вам нужно будет взглянуть на загрузчик ОС и посмотреть, как они выполняют настройку компилятора (и во многих случаях вам также понадобятся специальные инструменты для создания кода, который находится в определенном месте, подходящем для загрузки в память). и прямо исполнено). Эта страница может быть полезна для этого (я не прочитал все это, она может даже сказать, сколько у вас памяти): http://www.codeproject.com/Articles/36907/How-to-develop-your-own-Boot-Loader
РЕДАКТИРОВАТЬ: моя ошибка, вики правильно, просто оставив это здесь, потому что …
Похоже, в вики есть опечатка — строка:
mov edx,0x0534D4150
должен выглядеть так:
mov edx,0x050414D53
Обратите внимание, что байты расположены в обратном порядке (поскольку x86 имеет младший порядок байтов).