Page 14 of 15

Posted: Sun Jan 07, 2007 6:57 pm
by Serge
maxxx

Для программ в примере testcon2.asm есть функции link и get_proc. Проще и быстрее включить их код в программу чем делать системный вызов. Особенно с фунцией link которая сама делает всё необходимое связывание. get_proc нужна только если требуется адрес конкретной функции.

Posted: Sun Jan 07, 2007 7:48 pm
by Serge
Чтобы не возиться с ассемблерными вставками надо объявить все импортируемые функции через указатели

Code: Select all

//это вариант для MSVC

extern void (_stdcall *dll_start)(int);
extern void (_stdcall *con_init)(dword wnd_width, dword wnd_height,
       dword scr_width, dword scr_height, const char* title)
extern void (_stdcall *con_write_asciiz)(dword flags, const char* string);

if( !dll_start(DLL_ENTRY))
{

//что-то не так

  exit();

}
в asm файле

Code: Select all

imports:
_dll_start          dd szStart
_dll_ver            dd szVersion
_con_init           dd szcon_init
_con_write_asciiz   dd szcon_write_asciiz
_con_printf         dd szcon_printf
_con_exit           dd szcon_exit
                    dd 0                //завершает массив

szStart             db 'START',0
szVersion           db 'version',0
szcon_init          db 'con_init',0
szcon_write_asciiz  db 'con_write_asciiz',0
szcon_printf        db 'con_printf',0
szcon_exit          db 'con_exit',0
я не знаю если способ создать массив imports на C. Вероятно потребуется очень громоздкое приведение типов из указателя на строку в указатель на функцию если оно вообще возможно.

Posted: Sun Jan 07, 2007 9:28 pm
by maxxx
Serge wrote:maxxx

Для программ в примере testcon2.asm есть функции link и get_proc. Проще и быстрее включить их код в программу чем делать системный вызов. Особенно с фунцией link которая сама делает всё необходимое связывание. get_proc нужна только если требуется адрес конкретной функции.
для разработчика будет проще вызвать загрузку dll которая уже реализована в ядре, и вызвать функцию загрузки как массива импортируемых функций, так и отдельную функцию.

в любом случае в ядре уже реализованы как get_proc (одна функция), так и get_proc_ex (массив), так зачем прикладному программисту каждый раз включать в свой код процедуру get_proc/ex если можно их сделать доступными?

ядро должно предоставлять не только загрузку длл но и получение адреса функции из длл обеих версий посредством системных вызовов. лишний раз городить код в программе неразумно, если есть его аналоги в ядре

Posted: Tue Jan 09, 2007 12:14 am
by Serge
maxxx

get_proc из ядра не годится для приложений. У ядра базовый адрес сегментов 0 а у программ std_application_base_address. Всё равно придется делать новую функцию и учитывать это смещение. Лучше разработать новый вариант заголовка, чтобы загрузчик мог сам загружать DLL и делать связывание.

Posted: Tue Jan 09, 2007 4:40 am
by maxxx
Всё равно придется делать новую функцию и учитывать это смещение. Лучше разработать новый вариант заголовка, чтобы загрузчик мог сам загружать DLL и делать связывание.
...было бы просто замечательно :)

Posted: Fri Feb 02, 2007 9:12 pm
by andrew_programmer
У меня вопрос по DLL.Как выделять в DLL память под стек ?

Я пишу одну DLL-ку.Она работает,если не передавать параметров через стек.А если передавать параметры через стек,то DLL не работает(глюки всякие появляются).

Posted: Fri Feb 02, 2007 10:19 pm
by Serge
andrew_programmer
ДЛЛ использует стек программы, так что ничего не надо выделять. Проверь передачу параметров и очистку стека после вызова, ещё лучше использовать макросы из proc32.inc ( proс, stdcall и т.д) примеры есть в исходниках ядра core/dll core/heap

Posted: Fri Feb 02, 2007 11:49 pm
by andrew_programmer
Вот пример DLL:

Code: Select all

format MS COFF

public EXPORTS

section '.flat' code readable align 16

align 4
test_dll:

      pop [v2]
      pop [v1]

      mov eax,13
      mov ebx,20*65536+100
      mov ecx,50*65536+100
      mov edx,0xffffff
      int 0x40

      ret

align 16
EXPORTS:
		dd szTest,test_dll
		dd 0

szTest		db 'test_dll',0


section '.data' data readable writable align 16

v1     rd 1
v2     rd 1
А вот программа,загружающая эту DLL:

Code: Select all

use32
	db	'MENUET01'
	dd	1
	dd	start
	dd	i_end
	dd	0x1000
	dd	0x1000
	dd	0
	dd	0

start:
	call draw_window

	mov	eax, 68
	mov	ebx, 19
	mov	ecx, dll_name
	int	0x40
	test	eax,eax
	jz	exit

	mov ebx,[eax+4]
	mov [test_dll],ebx

        push 1
        push 2

	call [test_dll]

	mov eax,5
	mov ebx,200
	int 0x40


exit:
	or	eax, -1
	int	0x40

draw_window:

	mov eax,12
	mov ebx,1
	int 0x40

	xor eax,eax
	mov ebx,100*65536+300
	mov ecx,100*65536+300
	mov edx,0x03aabbcc
	int 0x40

	mov eax,12
	mov eax,2
	int 0x40

	ret

;DATA
dll_name db '/hd2/1/KOLIBRI/develop/testdll/dll',0

align 4
test_dll dd 0

i_end:
Код простой,но не работает.Почему - я незнаю.

Posted: Sat Feb 03, 2007 5:39 am
by Serge
andrew_programmer
Не забывай что call записывает в стек адрес возврата

pop [v2] загрузит из стека адрес возврата
pop [v1] загрузит 2

ret загрузит 1 и запишет ее в eip

замени код на

mov eax, [esp+4] ;2
mov ebx, [esp+8], 1

mov [v1], ebx
mov [v2], eax

ret замени на ret 8
или после вызова функции добавь add esp,8
иначе будет разрушен стек

ещё раз рекомендую макросы из proc32.inc с их помощью можно создавать в стеке локальные переменные, что очень удобно.

Posted: Sat Feb 03, 2007 12:08 pm
by andrew_programmer
Serge

Большое спасибо за совет.

Posted: Tue May 29, 2007 11:14 am
by Sirius
При написании DLL уже можно использовать Fast System Call's?

Posted: Tue May 29, 2007 10:13 pm
by Ghost
Да запросто

Posted: Fri Jun 08, 2007 11:20 am
by Alver
Я не понял а на SVNе лежат исходники DLLей которые есть в дистре или нет? Я чтото найти не могу.

Posted: Sat Jun 09, 2007 11:25 am
by mike.dld
Alver
На SVN их пока что нет, но я думаю исправить эту ситуацию. Просто, это был как бы эксперимент, и я не знал, во что он выльется :)
Сейчас их можно взять на мойм сайте: (7z|zip)

Re: Менеджер DLL в MeOS

Posted: Thu Oct 09, 2008 11:16 pm
by NEOVIS
Здравствуйте!
Будет ли такой DLL код работать?

Code: Select all

format MS COFF
public EXPORTS

section '.flat' code readable align 16

_ADDNumbers@8:
push ebp
mov ebp, esp
sub esp, 4
mov dword  [ebp-4], 0
mov eax, 100
mov dword  [_A], eax
mov eax, dword  [ebp+12]
add eax, dword  [ebp+8]
mov dword  [ebp-4], eax
mov eax, dword  [ebp-4]
mov esp, ebp
pop ebp
ret 8

align 16
EXPORTS:
dd    szADDNumbers@8,_ADDNumbers@8
db   0,0

szADDNumbers@8   db  'ADDNumbers@8',0

section '.bss' data readable writable
align 4
        _A:   rb 4
        _C:   rb 8
        _B:   rb 12
        _D:   rb  8

section '.data' data readable writable
align 4
_Lt_0007:       db      "Hello",0
_Lt_0008:       dq      32768
_Lt_000B:       db      "Hello World!",0
И ещё пару вопросов, о DLL.

Импортируемые функции - Должны обязательно находится в секции '.flat' или его можно вписать в секцию '.data' или так:

Code: Select all

section '.export' data readable writable
EXPORTS:
dd    szADDNumbers@8,_ADDNumbers@8
db   0,0

szADDNumbers@8   db  'ADDNumbers@8',0
Заранее, спасибо!