Самый маленький эльф Крис Касперски ака мыщъх Хакер, номер #090, стр. 090-110-2 Простейшая ассемблерная программа elf_libc.S .text .global main main: pushl $len pushl $msg pushl $1 call write addl $12, %esp ret .data msg: .ascii "hello,elf\n" len = . - msg Чтобы вдохнуть в ассемблерный файл жизнь, его необходимо прогнать через транслятор, чем мы сейчас и займемся: $ gcc -o elf_libc elf_libc.S $ ./elf_libc hello,elf На диске образуется файл elf_libc, победоносно выводящий "hello,elf" на экран, но занимающий при этом целых 12,096 байт (при трансляции под FreeBSD – 4,270). Ну и монстр! Куда это годится?! А все потому, что компилятор самовольно прицепил символьную информацию, которая нам совершенно ни к чему. К счастью, ее очень легко отрезать штатной утилитой strip. $ strip elf_libc Файл сразу же похудел до 2,892 байт (под FreeBSD — до 2,744), полностью сохранив свою работоспособность. С таким размером уже можно жить (особенно под FreeBSD, где у мыщъха установлена старая версия компилятора). Естественно, сама операционная система тут ни при чем. А теперь, отказавшись от услуг gcc, попробуем собрать файл вручную. Под FreeBSD это осуществляется так: $ as -o elf_libc.o elf_libc.S $ ld -s -o elf_libc /usr/lib/crt1.o elf_libc.o -lc На диске образуется файл elf_libc размером всего 2,108 байт, что на 636 байт короче сборки gcc с последующим стрипаньем символьной информации. То есть "ручная" сборка намного эффективнее! C Linux'ом и Solaris'ом в этом плане сложнее, да и не совсем понятно, где у них расположен стартовый код. Но это еще полбеды. Стартовый код содержит дикие зависимости, влекущие за собой дополнительные библиотеки, находящиеся в самых непредсказуемых местах. Что же делать? Приходится обращаться за помощью к gcc. Уж он-то наверняка знает, где расположены его библиотеки. Ассемблируем файл транслятором as и передаем полученный elf_libc.o на компоновку компилятору gcc. Стрипаем символьную информацию и получаем те же самые 2,892 байт, что и при автоматической сборке. $ as -o elf_libc.o elf_libc.S $ gcc elf_libc.o -o elf_libc $ strip elf_libc Выходит, что "полуавтоматическая" сборка под Linux'ом дает тот же самый результат, что и автоматическая, поэтому никакого смысла работать руками здесь нет. Отладка ассемблерных программ Редкая программа начинает работать сразу же после запуска. Практически всегда она содержит ошибки, требующие отладки. Высокоуровневые программисты находятся в более выгодном положении, поскольку значительная часть ошибок отсеивается компилятором еще на стадии трансляции, к тому же сам синтаксис языка делает программу более выразительной. Одиночные ассемблерные команды в отрыве от своего окружения — абсолютно бессмысленны, и обнаружить ошибку путем визуального просмотра листинга очень тяжело. |