| 
| 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 ;пишем операцию которую нужно написать.
 .... ;другие фиксы оффсетов данных, файлов,
 .... ;и вставка прыжков на код.
 |  |  |  |  |