Вот такой пример для наглядности
Код:
STACK_SIZE equ 4096
include 'proc32.inc'
org 0
db 'KOLIBRI',0 ;+00 banner + revision 0-255
dd start ;+08 application entry
dd ecode ;+12 end of code and constant data
dd import ;+16 import section, if present
dd eimport ;+20 end of import section
dd edata ;+24 end of initialized data, end of disk image
dd emem ;+28 end of uninitialized data
dd STACKSIZE ;+32 size of stack
dd 0 ;+36 address of tls info structure kernel-defined
dd 0 ;+38 exec_path kernel-defined
dd 0 ;+40 cmdline kernel-defined
dd 0 ;+44 env kernel-defined
exec_path equ 38
.code:
start:
...
...
align 8
main:
cinvoke _printf, msg_hello, [exec_path]
xor eax, eax
ret
msg_hello db '%s: Hello world!',0x0D,0x0A,0
ecode:
align 16
import:
library libc,'libc.dll'
include 'libc.inc'
eimport:
;place initialized data here
align 16
.data:
...
...
edata:
;place unitialized data here
align 16
.bss:
...
...
emem:
ailign 16
tlsinfo rd 1 ;tls mutex kernel-defined
tls_map rb 128 ;kernel-defined
Основные отличия от использующихся заголовков:
- Вместо значения esp приложение указывает необходимый размер стека.
- ядро размещает в стеке полный путь к приложению, командную строку и переменные окружения и устанавливает указатели в заголовке
- структура tlsinfo необходима для синхронизации доступа к tls в многопоточных приложениях.
многопоточные (thread safe) dll не должны работать в приложениях без tlsinfo
ABI //TBD