Экстремальная оптимизация или гонка на виражах
Держитесь! Мы вошли в раж и не оторвемся от клавиатуры, пока не сократим файл хотя бы на десяток байт. Больше всего нас раздражают e_ident
байты, оставленные для выравнивания в количестве целых девяти штук. Плюс один байт версии elf-файла, которую все равно никто не проверяет! А что если... разместить строку "hello,elf" именно здесь?! Сказано— сделано! Ведь elf-заголовок отображается на память и вполне пригоден для хранения переменных.
Но это еще не все! Даже поверхностный взгляд показывает, что 8 последних байт elf-заголовка совпадать с 8 первыми байтами program header table, следующего непосредственно за ним. вот они, красавчики: 01h 00h 00h 00h 00h 00h 00h 00h 01h 00h 00h 00h 00h 00h 00h 00h. А почему бы не сдвинуть начало program header table так, чтобы оба заголовка перекрывались? Для этого будет достаточно всего лишь скорректировать поле e_phoff, переместив метку phdr
вглубь elf заголовка.
Оптимизировав служебные структуры насколько это возможно, займемся "несущим" кодом. Команда MOV EAX, 4
отъедает целых 5 байт, но если немного подумать, можно "отвоевать" 1 байт, заменив ее эквивалентной конструкцией: XOR EAX,EAX/MOV AL, 4. Тоже самое относится и MOV EDX,MSG_END-MSG.
Проделав все эти операции, мы получим следующий файл:
BITS 32
org 8048000h
ehdr: ; // Elf32_Ehdr
; db 7Fh, "ELF", 1, 1, 1 ; // e_ident
db 7Fh, "ELF", 1, 1 ; // e_ident
; // размещаем выводимую строку в поле e_ident
; // в EI_PAD байтах, оставленных для выравнивания
; // "захватывая" и байт EI_VERSION
msg db "hello,elf",0Ah
msg_end:
dw 2 ; // e_type
dw 3 ; // e_machine
dd 1 ; // e_version