· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› CALL

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Мар 12, 2004 00:48:05

Премного извиняюсь за столь идиотский вопрос (мне правда стыдно :((, но почему не работает следующее:

PMSEG segment para public 'CODE' use32
  ...
  mov edx, offset label
  call edx ; понятно, чего я хочу
  ...
label:
PMSEG ends

; Или как вариант:
PMSEG segment para public 'CODE' use32
  ...
  push offset label
  retn
  ...
label:
PMSEG ends


Всё сие действо происходит в PM, но по-моему это не повод, чтобы не работать. При этом call label работает замечательтно. Кто предумает, заодно укажите как это будет в случае 1, если вместо регистра, нужный адрес хранится в переменной, которая находится в аналогичном сегменте, но только 'DATA'


Дата: Мар 12, 2004 01:16:17

А что происходит-то? Ну сделал ты свой регистровый вызов, а что потом? GPF?


Дата: Мар 12, 2004 01:54:56

Если верить моему обработчику ошибок, то Unknown command, хотя чего-то меняя (по-моему сегментные регистры) и GPF схлопатал. Код call edx : FF D2, в реальном работает превосходно, а тут чё-то совсем не понятное


Дата: Мар 13, 2004 03:34:41

Вообще то всё правильно. call edx должен работать так, как ты хочешь. Вопрос в том, что идет после
label:
PMSEG ends
Ты трассировал это под отладчиком?


Дата: Мар 13, 2004 16:12:59

Дело в том, что на самом деле label - это процедура, причём вида label proc. Эта процедура читает физический сектор и входит в ядро моей ОС. Мне захотелось вызывать её не на прямую (call label), а так: call var, где var содержит смещение процедуры. Это надо для того, чтобы я всегда мог подменить реальную процедуру любой другой. Сначала я думал, что всё не работает только потому, что переменная находится в сегменте данных, а процедура - кода, но когда я написал:
  mov ebx,offset label
  call ebx

то не получил ничего из того что хотел. Я не понимаю:(. Процедура лежит в том же сегменте, что и её вызов, т.е. тип near. В real'e работает идеально подобное действие. Может P-mode надо настраивать особо. Я даже записал сие в кодах, дабы проверить, не ошибся ли компилятор, но не помогло... Затем я нагрешил на COM-файл, но тоже зря - в exe-шниках тоже самое...


Дата: Мар 13, 2004 17:35:37

Все равно ничего не понятно :-( Что не работает то?! Покажи весь кусок кода.


Дата: Мар 13, 2004 19:01:25

И gdt.

Может быть ты малость напутал с размерами операнда/адреса и тп Или заехал за границу сегмента. Неплохо бы вывести все данные в обработчике на экран.


Дата: Мар 13, 2004 21:15:03

Во-первых, на счёт отладчика :). Мне который раз советают сие граждане посмотреть этот баг под отладчиком. Вынужден признаться, что не знаю как это сделать, ибо мне не известен отладчик который мог бы отладить ДОС com-файл, содержащий два вида режима работы проца. Ну да не об этом. Дабы далеко не ходить, пресылаю попросту немного переделанный код Зубкова (книга такая клёвая про асм, если кто не читал) который запарывается на том же самом, судите<:(
	.model tiny
	.code
	.486p
	org	100h

start:	mov	cs1,cs				; load real segment address

; Opening A20
	in	al,92h
	or	al,2
	out	92h,al

; Count linear address of pm_entry
	xor	eax,eax
	mov	ax,cs
	shl	eax,4
	mov	ebx,eax
	add	eax,offset pm_entry
	mov	pm_entry_addr,eax

; Count base for gdt_16bit_cs_l
	mov	eax,ebx
	mov	word ptr gdt_16bit_cs_l+2,ax
	shr	eax,16
	mov	byte ptr gdt_16bit_cs_l+4,al

; Count linear address of gdt
	mov	eax,ebx
	add	eax,offset gdt
	mov	dword ptr gdtr+2,eax

; Load GDT
	lgdt	fword ptr gdtr

; Disable interrupts
	cli
	in	al,70h
	or	al,80h
	out	70h,al

; Start protected mode
	mov	eax,cr0
	or	al,1
	mov	cr0,eax

; Go to 32-bit flat code segment
		db	66h
		db	0EAh
pm_entry_addr	dd	?
		dw	SEL_FLAT_CS

;********************************************************************* *******

; Return to real mode

pm_ret:
	mov	eax,cr0
	and	al,0FEh
	mov	cr0,eax

; Reset prefetch queue
	db	0EAh	; jmp
	dw	$+4	; next command
cs1	dw	?	; cs

; Enable interrupts
	in	al,70h
	and	al,07Fh
	out	70h,al
	sti

; Exit
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;
;; RM DATA                                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;
gdt	label	byte
		db	8 dup(0)
gdt_flat_cs	db	0FFh,0FFh,0,0,0,10011010b,11001111b,0
gdt_flat_ds	db	0FFh,0FFh,0,0,0,10010010b,11001111b,0
gdt_16bit_cs_l	db	0FFh,0FFh,0,0,0,10011010b,0,0
gdtr		dw	$-gdt-1
		dd	?

SEL_FLAT_CS		equ	00001000b
SEL_FLAT_DS		equ	00010000b
SEL_16BIT_CS_LOCAL	equ	00011000b

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;
;; PM ENTRY                                                                ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;
PMSEG	segment	para	public	'CODE'	use32
	assume	cs:PMSEG
pm_entry:
	mov	ax,SEL_FLAT_DS
	mov	es,ax
	mov	edi,0B8000h

; Эти две строки печатают две буквы 'p' на экране
	call	z
	call	z

; А эта строка запарывает всю систему
      mov esi,offset z
      call esi

; Exit PM
	db	0EAh
	dd	offset pm_ret
	dw	SEL_16bit_CS_LOCAL

z:	mov	word ptr es:[edi],7070h
	add	edi,2
	ret
PMSEG	ends
	END	start

Компилится сие masm 6.11 или подобным. Смотрите, если я конечно в чём-нибудь не прав, сильно не ругайтесь. Я ещё юзер в PM (:<(, по крайней мере в исправление неизвестного мне.
P.S. если кто действительно знает такие отладчики (см.выше), просьба указать место, где их взять за бесплатно (денег у меня вообще 0xFFFFFFFF+1)


Дата: Мар 13, 2004 22:31:17 · Поправил: Valery

Иисус Мария, а как вообще хоть один call без стека работает? У тебя же остался досовский стек! Замени call/ret на jmp/jmp и еще раз проверь. Может и не в этом дело, но все равно так нельзя. Попробуй еще для единообразия сделать все use 16 с префиксами. И еще раз проверь значения в дескрипторах - лень за тобой смотреть.
Наконец, выведи на экран offset.

PS Это и есть твоя ось?


Дата: Мар 13, 2004 22:37:22

Это не ось :-) и даже не кусок, что касается стека, он остаётся досовым, ну и что???


Дата: Мар 13, 2004 22:56:16

Область памяти под него всеравно выделена. И ещё, ты сам то JMP проверял??? У меня не пашет. На счёт use 16 с префиксами вообще не понял причём здесь они, а вывести на экран offset (я так понял для проверки его правильности) то оно-то всегда правильное. В этом всё и дело, что инструкция правильная, но не работает. Вопрос: а этот исходник у тебя запустился? Если да, обязательно скажи, буду простреливать себе голову и обе руки :-)


Дата: Мар 13, 2004 23:08:05

Kirk
offset z это смещение относительно начала PMSEG (или CODEGROUP?), а дескриптор gdt_flat_cs описывает сегмент с базой = 0. Программа то не с нулевого адреса загружена!


Дата: Мар 14, 2004 00:01:08

Большое человекское спасибо тебе, Black_mirror, действительно я не подумал об этом. Эту часть брал у Зубкова и мне даже в голову не пришло, что там сегмент кода может быть нулевым (правда там это было для EXE-файла и для тех примеров, которые там, данная проблема роли не играла). Хотя как АСМ'овец, я конечно каюсь, я должен был это предвидеть, но видимо я ещё духовно не вырос в свои 19 :-(. Пойду дзен-философию изучать и духовно совершенствоваться. Спасибо ещё раз, не знаю, когда бы я сам решил эту проблему :-)


Дата: Мар 14, 2004 00:02:49 · Поправил: Valery

Мда, давно не грузился я досовским загрузчиком...

Kirk

Если уж вычислять адрес кода в рантайме, то может тебе поможет вот этот тред:

http://www.wasm.ru/forum/index.php?action=vthread&forum=3&topic=5192
("Определение ip")

Это как раз то самое - когда офсет неизвестен. Хотя настоящую jump table так делать накладно будет:)


Дата: Мар 14, 2004 03:15:35

Kirk
Можно очень сильно упростить себе жизнь сделав два дескриптора(для кода(32х-битный) и для данных),с базой там, куда загрузилась программа(перед переключением в PM придется их малось подправить), и лимитом 64К. А третий дескриптор пусть описывает всю память. Все сегменты(и 16, и 32 битные) объединяешь в одну группу. И пишешь: assume cs,ds,ss: mygroup. Вряд ли в ближайшее время размер твоей ОС превысит 64К. А так можно избежать головной боли с вычислением смещений.

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.049