Вопрос по VMWare

Papazyan

Виртуальная машина в VMWare виснет в 16-битном режиме при исполнении команд

mov ebx, 0xffff
inc ebx
mov dl, [ebx]

inc, наверно, необязателен, можно сразу по 0x10000 обратиться, но мне лень проверять. Виснет на последней команде. Является ли это багом или просто undefined behaviour? Ведь, в принципе, не факт, что в 16-битном режиме можно использовать регистры типа ebx и еще косвенно по ним обращаться. Но на нормальной машине это работает.

evgen5555

В 16-битном режиме EBX недоступен.

Papazyan

В 16-битном режиме EBX недоступен.
Практика показывает, что доступен (в том числе и на VMWare).

evgen5555

Хреновая, значит, практика

Marinavo_0507

> Ведь, в принципе, не факт, что в 16-битном режиме можно использовать
> регистры типа ebx и еще косвенно по ним обращаться.
Думаю, факт. Поищи в интеловских спеках. Нужно просто префикс какой-то поставить, и команда становится 32-битной. Я в детстве писал что-то такое, помнится.
Виснуть на непривилегированном коде эмулятор всё равно не должен, вне зависимости от спеков.

evgen5555

http://www.vmware.com/pdf/ws55_bugs_fixed_since500.pdf

119891 Under specific, rare circumstances, running 16-bit DOS applications in a
Windows guest causes direct execution errors in V8086 mode. This fix prevents
direct execution errors that are caused by the sysenter instruction being
improperly handled, and thus enables DOS applications to execute properly.

Это не оно?

Papazyan

Нет. Я пытался поискать это, но нифига не нашел. Не понятно, как искать.
Виснет загрузчик ядра при проверке своей чек суммы. Так что любые OS тут побоку.

SPARTAK3959

Использовать ebx в 16-битном коде можно, но в данном случае у тебя возникает выход за пределы сегмента, что приводит к исключению, которое по-видимому некорректно обрабатывается vmware.

Papazyan

Использовать ebx в 16-битном коде можно, но в данном случае у тебя возникает выход за пределы сегмента, что приводит к исключению, которое по-видимому некорректно обрабатывается vmware.
А на машине оно возникает? Его же никто не обрабатывает, не понятно почему тогда все нормально.

SPARTAK3959

Должно возникать, если прога не находится в нереальном режиме (16-битный режим с лимитами сегментов 4Гб). А вот что делает его стандартный обработчик и что происходит после этого - более интересный вопрос. Тут надо читать доки интела. Мне кажется, что на реальной машине будет зависание.

Papazyan

По факту виснет только в VMWare. Код 16 бит, режим реальный.

SPARTAK3959

Понимаешь, если кто-то написал [ebx] вместо [bx], то он либо ошибся, либо подразумевал нереальный режим. Ты уверен, что прога не переходит в нереальный режим (в этом случае должны быть либо команды mov cr0,* либо int 31h (DPMI? Если уверен, то заменяй [ebx] на [bx] (можно вместо префикса поставить nop для этого) и не мучайся.

smit1

mov ebx, 0xffff
inc ebx
mov dl, [ebx]
А в ds у тебя что?

Papazyan

Вот этот код, короче, записанный в MBR выдает No active partition found два раза на обычном железе и один раз в VMWare.

; ************************************************************
;
; 0 block hard disk loder
;
; This is 16 bit real-mode assembly code
; This code is compiled with the nasm assembler
;

LOAD_ADDRESS equ 0x7c00
PROG_START equ 0x700

BOOT_IND0 equ (PROG_START + 0x1be)
BOOT_IND1 equ (PROG_START + 0x1ce)
BOOT_IND2 equ (PROG_START + 0x1de)
BOOT_IND3 equ (PROG_START + 0x1ee)

READ_SECTORS equ 0x02
DISK_PARAMS equ 0x08

STACK_LOCATION equ (0x1000 - 8)

; ----------------------------------------------------------------
; BSS section
absolute 0x600
lgdtp resb 6 ; reserving space to align with pb0 code
sec_per_track resw 2
sec_per_cylinder resw 2
boot_drive_num resb 1

section .text
org 0x700

; This code is initially loaded at address 0x7c00
; The code before begin_pdc (begin position dependant code)
; will relocate the 512 byte block to 0x700 and jump to
; begin_pdc. cs, ds, es, and ss will be set to 0 during the relocation
; process.

jmp short start ; Part of the magic number for block 0
start:
cli
xor ax, ax
mov ss, ax
mov ds, ax
mov es, ax
mov sp, STACK_LOCATION
mov si, LOAD_ADDRESS
mov di, PROG_START
mov cx, 512/2
rep movsw
jmp 0:begin_pdc
;
; This is the start of the position dependent code.
; the following have been set:
; cs = 0, ds = 0

begin_pdc:

mov si, noactive
call print_string

; ZOPA START
mov ebx, 0xffff
inc ebx
mov eax, [ebx]
; ZOPA END

mov si, noactive
call print_string

spin:
jmp spin

print_string:
lodsb
and al, al
jz return
mov ah, 0xe
mov bx, 0x7
int 0x10
jmp print_string

return:
ret

noactive db 'No Active Partition Found', 0

Marinavo_0507

А нафига такой странный код нужен-то?

Papazyan

А нафига такой странный код нужен-то?
Я убрал нерелевантный код.

Marinavo_0507

Я понял.
Вопрос был в том, зачем загрузчик так делает.

Ivan8209

> Понимаешь, если кто-то написал [ebx] вместо [bx], то он либо ошибся, либо подразумевал нереальный режим.
Наглая ложь!
---
...Я работаю антинаучным аферистом...

Papazyan

Вопрос был в том, зачем загрузчик так делает.
Это другой загрузчик делает, считает чек сумму (смещение может быть больше 64k). Я просто тест-кейс привел, самый простой, чтоб все понятно было.

yolki

а разве в реальном режиме регистры eXX можно использовать?

Papazyan

а разве в реальном режиме регистры eXX можно использовать?
Господа, я привел программу первоисточник. На железе она работает, на VMWare нет. Объяснить почему я не могу, не особо разбираюсь в тонкостях интел-архитектуры.

Ivan8209

Можно.
---
"Расширь своё сознание!"
Оставить комментарий
Имя или ник:
Комментарий: