Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| |
Попробуй nasm - он умеет Intel нотацию 13.02.02 12:57 Число просмотров: 966
Автор: XR <eXtremal Research> Статус: The Elderman Отредактировано 13.02.02 17:46 Количество правок: 1
|
NASM
|
<programming>
|
[Unix] ASM 31.01.02 23:10
Автор: 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'ом... что ему не хватает ?
Чем вообще происходит вызов моего кода call или jmp ? Если call, то вроде мой рет уместен, если джампом, то как мне сообщить ядру, что я завершился ?
Вроде вопросы понятны. Надеюсь на ответы по существу.
Сенькс.
|
|
[Unix] ASM 13.02.02 09:38
Автор: vp016 Статус: Незарегистрированный пользователь
|
Sorry :), пока регистрировался не заметил что ты сам разобрался:).
Привычный ассемблер (в смысле win32 & etc) - nasm. Только у меня
с ним обратные проблемы :), as из под unix мне больше нравится:).
|
|
[Unix] ASM 13.02.02 09:29
Автор: vp016 Статус: Незарегистрированный пользователь
|
> Так, кто может объяснить насильнику, что вообще происходит. > Имею простейшубю прорамульку: > .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
|
По второму вопросу:
<p>
.globl main, main2
main:
movl $1, %eax
int $0x80
main2:
jmp main2
<\p>
Где 1 - смещение ф-ии sys_exit в таблице system_call_table; 0x80 - прерывание для вызова системных ф-ий.
ld -e main m.o
Приводит к нормальному выходу.
ld -e main2 m.o
Приводит к зацикливанию.
Как и написано в man - ключ -e устанавливает точку входа.
Вот только где бы достать "нормальный" ассемблер. А то слишком непривычно аргументы наоборот записывать...
|
| |
Попробуй nasm - он умеет Intel нотацию 13.02.02 12:57
Автор: XR <eXtremal Research> Статус: The Elderman Отредактировано 13.02.02 17:46 Количество правок: 1
|
NASM
|
|
Пояснения: [Unix] ASM 01.02.02 14:08
Автор: DPP <Dmitry P. Pimenov> Статус: The 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
Иначе к системе не обратиться, она в другом адресном пространстве,
а переключение контекста только интерраптом.
> Вроде вопросы понятны. Надеюсь на ответы по существу. > Сенькс.
|
| |
Пояснения: [Unix] ASM 01.02.02 17:23
Автор: SEH Статус: Незарегистрированный пользователь
|
> > Так, кто может объяснить насильнику, что вообще > происходит. > > Имею простейшубю прорамульку: > > .globl main > > main: > > ret > > > > Собираю gcc t1.s > > OK. Усе работает. Размер файла (внимание) 3898 байт > !!! Не > > многовато л и ? > > Нет не мнгогвато - запускач разбирает командную строку и а не шелл(или вызывающий процесс) этим занимается?
|
| |
Добавка про GCC 01.02.02 14:32
Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
|
> Но как тогда понять слова, что gcc является крутым, оптимизирующим > компилером, на котором можно делать ядро ? Это не наезд, я просто > хочу понять.
GСС действительно на данный момент самый крутой компилятор
в отношение оптимизации времени выполнения, а не размера кода.
Все нормальные компиляторы по умолчанию оптимизируют по скорости
выполнения, а это обратно противоположно размеру кода. Примеры:
Чистить стэк быстрее ADD а не POP (память не затрагивается),
хотя POP меньше в памяти; выравнивание на границу строка кэша
NOPами, избавление от ветвлений... Убедиться в этом не сложно
все компиляторы умеют код в ассемблеровский текст генерить.
Не забывайте про оптимизационные ключи в командной строке.
GCC может такой код сгенерить, что потом исходник узнать невозможно.
Оптимизация скорости обычно важнее.
Если екзешка на диске (или ее код в памяти) будет
на один процент (порятод примерно такой) места больше занимать,
то это не так страшно при нынешних объемах НМД и ОЗУ, а даже несколько
процентов скорости (или FPS) - приятно.
> INT 20 или INT 21 при AH=0 Забыл про завершение без освобождения памяти (резидент).
|
|
|