> > Так, кто может объяснить насильнику, что вообще > происходит. > > Имею простейшубю прорамульку: > > .globl main > > main: > > ret > > > > Собираю gcc t1.s > > OK. Усе работает. Размер файла (внимание) 3898 байт > !!! Не > > многовато л и ? > > Нет не мнгогвато - запускач разбирает командную строку и а не шелл(или вызывающий процесс) этим занимается?
Так, кто может объяснить насильнику, что вообще происходит.
Имею простейшубю прорамульку:
.globl main
main:
ret
Собираю gcc t1.s
OK. Усе работает. Размер файла (внимание) 3898 байт !!! Не многовато л и ?
Пусть мой ret занимает один байт, на что тратятся остальные 3897 ? Ладно, будем считать, что линкер загнал мне всю рантайм библиотеку в приложение + добавил потдержку окон, фтп, и джава машину (подарочек типа). Но как тогда понять слова, что gcc является крутым, оптимизирующим компилером, на котором можно делать ядро ? Это не наезд, я просто хочу понять.
Вариант два: as -o t1.0 t1.s
ld -e main t1.o
Размер 673 (уже получше). Но, Сегментейшен фаулт, однако. Почему ? Точку входа задал, выхожу ret'ом... что ему не хватает ?
Чем вообще происходит вызов моего кода call или jmp ? Если call, то вроде мой рет уместен, если джампом, то как мне сообщить ядру, что я завершился ?
Вроде вопросы понятны. Надеюсь на ответы по существу.
Сенькс.
Sorry :), пока регистрировался не заметил что ты сам разобрался:).
Привычный ассемблер (в смысле win32 & etc) - nasm. Только у меня
с ним обратные проблемы :), as из под unix мне больше нравится:).
> Так, кто может объяснить насильнику, что вообще происходит. > Имею простейшубю прорамульку: > .globl main > main: > ret Короче говоря так. Адрес запуска программы _start а не main. Для того чтоб его поменять надо принудительно задать в ld. Пример:
ld -e main t.s -o t
Либо указать его в теле программы.
Программа заканчивает свою жизнь не по ret, а вызовом системы __exit 0
это что-то:
mov $0x01, %eax
int 0x80
после таких действий код будет занимать те же 700 байт и будет работать.
> Текст проги после некоторой модификации :):
.globl _start
_start:
mov $0x01, %eax
int 0x80
Все работает.
Разобрался. Может кому поможет:03.02.02 23:52 Автор: PS <PS> Статус: Elderman
> Так, кто может объяснить насильнику, что вообще происходит. > Имею простейшубю прорамульку: > .globl main > main: > ret > > Собираю gcc t1.s > OK. Усе работает. Размер файла (внимание) 3898 байт !!! Не > многовато л и ?
Нет не мнгогвато - запускач разбирает командную строку и окружение,
настраивает адреса на резидентную библиотеку, инициализирует
стэк, "кучу" памяти, запоминает время начала выполнения программы
для определенных библиотечных функций.
> Пусть мой ret занимает один байт, на что тратятся остальные > 3897 ? Ладно, будем считать, что линкер загнал мне всю > рантайм библиотеку в приложение + добавил потдержку окон, > фтп, и джава машину (подарочек типа). Но как тогда понять > слова, что gcc является крутым, оптимизирующим компилером, > на котором можно делать ядро ? Это не наезд, я просто хочу > понять.
В этом случае выполняемый файл может и мегабайтный размер иметь.
> Вариант два: as -o t1.0 t1.s > ld -e main t1.o
В данном случае в выполняемом модуле кроме одного байта кода
еще и заголовок прописан. Даже в ДОСе екзешка из одного байта кода
далеко не один байт на диске занимает.
> Размер 673 (уже получше). Но, Сегментейшен фаулт, однако. > Почему ? Точку входа задал, выхожу ret'ом... что ему не > хватает ?
Ты не точку входа задал, а глобальную переменную.
Интересно куда ты retом в этом случае вернуться хочешь,
запускателя уже нет, да и стэк пуст, адресное пространство
затачи - 1 байт - в любом случае сегментэишн зафаултится.
> Чем вообще происходит вызов моего кода call или jmp ? Если
В случае С программы обращение к main через call, а в данном
случае переключением контекста.
> call, то вроде мой рет уместен, если джампом, то как мне > сообщить ядру, что я завершился ?
Даже в ДОСе интерраптом нормально процесс завершается.
INT 20 или INT 21 при AH=0
Иначе к системе не обратиться, она в другом адресном пространстве,
а переключение контекста только интерраптом.
> Вроде вопросы понятны. Надеюсь на ответы по существу. > Сенькс.
> > Так, кто может объяснить насильнику, что вообще > происходит. > > Имею простейшубю прорамульку: > > .globl main > > main: > > ret > > > > Собираю gcc t1.s > > OK. Усе работает. Размер файла (внимание) 3898 байт > !!! Не > > многовато л и ? > > Нет не мнгогвато - запускач разбирает командную строку и а не шелл(или вызывающий процесс) этим занимается?
Добавка про GCC01.02.02 14:32 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Но как тогда понять слова, что gcc является крутым, оптимизирующим > компилером, на котором можно делать ядро ? Это не наезд, я просто > хочу понять.
GСС действительно на данный момент самый крутой компилятор
в отношение оптимизации времени выполнения, а не размера кода.
Все нормальные компиляторы по умолчанию оптимизируют по скорости
выполнения, а это обратно противоположно размеру кода. Примеры:
Чистить стэк быстрее ADD а не POP (память не затрагивается),
хотя POP меньше в памяти; выравнивание на границу строка кэша
NOPами, избавление от ветвлений... Убедиться в этом не сложно
все компиляторы умеют код в ассемблеровский текст генерить.
Не забывайте про оптимизационные ключи в командной строке.
GCC может такой код сгенерить, что потом исходник узнать невозможно.
Оптимизация скорости обычно важнее.
Если екзешка на диске (или ее код в памяти) будет
на один процент (порятод примерно такой) места больше занимать,
то это не так страшно при нынешних объемах НМД и ОЗУ, а даже несколько
процентов скорости (или FPS) - приятно.
> INT 20 или INT 21 при AH=0 Забыл про завершение без освобождения памяти (резидент).