Nemesis_c | Дата: Вторник, 02.08.2011, 22:36 | Сообщение # 1 |
Сообщений: 1148 Статус: Offline
| r57shell:
Code qwe equ 10 org $0 dс.b qwe
скомпилируем этот файл, получим файл, с одним байтом равным 10. почему? рассмотрим все команды 1) qwe equ 10. компилятор (ASM68k.exe) запоминает, что теперь qwe = 10. 2) org $0. out.seek(0) - перемещаемся в начало файла, которого ещё нет. 3) dc.b qwe - пишем байт, равный qwe, а qwe = 10 значит тоже самое что dc.b 0. 4) конец файла достигнут (in) переходим к следуйщему проходу, который поправляет не точные значения, которых в данном исходнике нет. такчто ничего не происходит, значит заканчиваем in.close() out.close()
второй пример с метками: Code org $10 dc.b "qweqweqwe" metka: dc.b $12 dc.l metka
1) org $10 переходим на адрес 10 2) dc.b "qweqweqwe" записываем побайтово строчку "qweqweqwe" 3) metka: - компилятор запомнит на каком он (курсор out) сейчас адресе, и теперь metka будет равен этому адресу. 4) dc.b $12 записываем байт $12 5) dc.l metka записываем 4 байта, равных по значению metka. metka = адресу где записано $12. то есть запишет оффсет на $12. 6) видим конец файла in, переходим к второму проходу, который опять же ничего не делает, т.к. не точностей нет, значит заканчиваем in.close() out.close()
пример где исползуется второй проход: Code org $0 dc.l file1 dc.l file2 file1: incbin file1.bin file2: incbin file2.bin
1) org $0 указываем позицию курсора явно 2) dc.l file1 пишем 4 байта равных значению file1. СТОП! как так, мы же не знаем чему равно file1! и вот хитрость, компиляторы обычно не тупые, и в этот же момент, они пишут 4 байта, чаще всего просто нули. и у себя, в памяти, запоминают, что сюда (в эти 4 байта), надо БУДЕТ записать значение file1. 3) dc.l file2 аналогично, пишет 4 нуля (обычно нуля) и запоминает, что надо будет "поправить" 4) file1: опа, метка, теперь адрес file1 = $8 (8 байтов уже написали) 5) incbin file1.bin - пишем то, что в файле file1.bin 6) file2: очередная метка, запоминаем положение курсора 7) incbin file2.bin - пищем то, что в файле file2.bin 8) видим конец файла, in.close(), переходим ко второму проходу. Тут есть чего править. Переходим на место, где должны были записать значение file1, и пишем $8 соответственно, а затем на место где должно было быть значение file2 (которе я не могу сказать, т.к. не знаю размер файла file1.bin, но вообще это будет размер file1.bin + $8 это должно быть очевидно), и записываем значение file2. другими словами, он записывает все значения, которые небыли известны во время первого прохода.
ещё оди пример, последний, примерно так выгледит сборщик рома. Code org $0 ;пишем с начала incbin rom.bin ;пишем оригинальный ром, или его кусок. org $12321 ;переходим на оффсет, с которого будем писать ;новые данные. file1: ;запоминаем место, где будет лежать file1.bin incbin file1.bin ;пишем file1.bin data1: ;запоминаем место, где будут лежать данные data1 dc.b $23 ;пишем побайтово эти данные dc.w $12 ;эти команды можно вынести в отдельный data1.asm, ;и тут написать include data1.asm .... ;остальные команды (данные) file2: ;запоминаем адрес, где будет лежать file2.bin incbin file2.bin ;пишем file2.bin code1: ;запоминаем адрес, где будет функция/код code1. mov (a0),d0 ;описываем функцию ... ;остальные команды функции/кода
org $1232 ;переходим на место, где должен быть ;указан адрес файла file1 dc.l file1 ;переписываем этот адрес на новый (меняем) org $2322 ;переходим на место, где должен быть ;указан адрес data1 dc.w data1 ;переписываем этот адрес на новый (меняем) org $123 ;переходим на место, где должен быть ;указан адрес data1 dc.l file2 ;переписываем этот адрес на новый (меняем) org $534 ;переходим на адрес операции, которую нужно ;заменить на jmp на наш код новый. jmp code1 ;пишем операцию которую нужно написать. .... ;другие фиксы оффсетов данных, файлов, .... ;и вставка прыжков на код.
|
|
| |