diff --git a/kvs_pass1.py b/kvs_pass1.py index 031ac8d..49d1b43 100644 --- a/kvs_pass1.py +++ b/kvs_pass1.py @@ -129,9 +129,29 @@ def add_byte(value: int, source: str = "", target=None, labels_list=None): if pending_labels: pending_labels = [] - def add_bss_entry(size: int, label: str = None): + global bss_size, vaddr_bnd + + bss_start = bss_size + bss_size += size + + # Виртуальный адрес начала блока + virt_addr = vaddr_bnd + bss_start + + entries.append(( + ".bss", # сегмент + "BSS", # файловый адрес (специальное значение) + f"0x{virt_addr:08x}", # виртуальный адрес + "", # байт + "", # уводящий адрес + f".резб {size}", # исходная команда + label if label else "", # приводящая метка + "", "", "" + )) """Добавляет запись для BSS в CSV """ +""" +def add_bss_entry(size: int, label: str = None): + global bss_size, vaddr_bnd bss_start = bss_size @@ -158,7 +178,7 @@ def add_bss_entry(size: int, label: str = None): "", # calc_target "0x00" # calc_byte )) - +""" def add_bytes(values, source: str = "", target=None): diff --git a/kvs_pass5.py b/kvs_pass5.py index 7701af5..e832c14 100644 --- a/kvs_pass5.py +++ b/kvs_pass5.py @@ -59,17 +59,20 @@ def analyze_csv(csv_file): except: pass - # BSS секция + # BSS секция (одна запись на блок) if seg == '.bss': if source and source.startswith('.резб'): - size = int(source.split()[1]) - virt_start = int(virt_addr_str, 16) - bss_blocks.append({ - 'virt_start': virt_start, - 'size': size, - 'label': label, - 'source': source - }) + # Формат: ".резб 1048576" + parts = source.split() + if len(parts) >= 2: + size = int(parts[1]) + virt_start = int(virt_addr_str, 16) if virt_addr_str else 0 + bss_blocks.append({ + 'virt_start': virt_start, + 'size': size, + 'label': label, + 'source': source + }) continue # Обычные секции @@ -105,7 +108,11 @@ def analyze_csv(csv_file): if sections['.data']['start'] and sections['.data']['end']: sections['.data']['size'] = sections['.data']['end'] - sections['.data']['start'] + 1 - return sections, bss_blocks, max_addr + # Вычисляем общий размер BSS и начальный виртуальный адрес + bss_total_size = sum(block['size'] for block in bss_blocks) + bss_start_vaddr = min((block['virt_start'] for block in bss_blocks), default=0) + + return sections, bss_blocks, max_addr, bss_total_size, bss_start_vaddr def generate_comment_data(): @@ -116,13 +123,9 @@ def generate_comment_data(): def generate_shstrtab_binary(has_bss): """Генерирует бинарную таблицу имён секций (как в kvs_8.py)""" - # Формат: \0.text\0.data\0.comment\0.shstrtab\0 - # (и .bss если есть) if has_bss: - # .text, .data, .bss, .comment, .shstrtab names = ['', '.text', '.data', '.bss', '.comment', '.shstrtab'] else: - # .text, .data, .comment, .shstrtab names = ['', '.text', '.data', '.comment', '.shstrtab'] result = b'' @@ -133,14 +136,10 @@ def generate_shstrtab_binary(has_bss): def create_null_section_entry(shdr_offset): - """Создаёт нулевую секцию (индекс 0) — все поля нулевые (sh_addralign=1 как в эталоне)""" + """Создаёт нулевую секцию (индекс 0) — все поля нулевые""" entries = [] - # 64 байта нулей для нулевой секции for j in range(64): - if 48 <= j <= 55: - byte_val = 0x01 if j == 48 else 0x00 - else: - byte_val = 0x00 + byte_val = 0x01 if j == 48 else 0x00 # sh_addralign = 1 entries.append({ 'сегмент': '.shdr', 'адрес': f"0x{shdr_offset + j:08x}", @@ -156,12 +155,16 @@ def create_null_section_entry(shdr_offset): return entries -def create_section_table_entries(sections, has_bss, shdr_offset, shstrtab_offset, comment_offset, comment_size, shstrtab_data): +def create_section_table_entries(sections, has_bss, shdr_offset, shstrtab_offset, + comment_offset, comment_size, shstrtab_data, + bss_start_vaddr, bss_total_size): """Создаёт записи таблицы секций для CSV (с нулевой секцией, .comment и .shstrtab)""" if DEBUG_PRINTS: print("\n[DEBUG] create_section_table_entries") print(f" has_bss = {has_bss}") + print(f" bss_start_vaddr = 0x{bss_start_vaddr:x}") + print(f" bss_total_size = {bss_total_size}") print(f" shdr_offset = 0x{shdr_offset:x}") print(f" shstrtab_offset = 0x{shstrtab_offset:x}") print(f" comment_offset = 0x{comment_offset:x}") @@ -169,26 +172,25 @@ def create_section_table_entries(sections, has_bss, shdr_offset, shstrtab_offset entries = [] - # Сначала добавляем НУЛЕВУЮ СЕКЦИЮ (индекс 0) + # Нулевая секция null_entries = create_null_section_entry(shdr_offset) entries.extend(null_entries) if DEBUG_PRINTS: print(f" Нулевая секция: {len(null_entries)} байт по адресу 0x{shdr_offset:x}") - # Смещение для следующей секции (после нулевой) next_offset = shdr_offset + 64 if DEBUG_PRINTS: - print(f" next_offset = 0x{next_offset:x} (начало заголовков секций)") + print(f" next_offset = 0x{next_offset:x}") - # Вычисляем индексы имён в .shstrtab в зависимости от наличия BSS + # Индексы в .shstrtab if has_bss: idx_text = 1 idx_data = 7 idx_bss = 13 - idx_comment = 17 - idx_shstrtab = 22 + idx_comment = 18 + idx_shstrtab = 27 # это харкод, если поменяю название сборщика - придется менять else: idx_text = 1 idx_data = 7 @@ -196,90 +198,59 @@ def create_section_table_entries(sections, has_bss, shdr_offset, shstrtab_offset idx_shstrtab = 22 if DEBUG_PRINTS: - print(f" Индексы в .shstrtab:") - print(f" idx_text = {idx_text}") - print(f" idx_data = {idx_data}") - if has_bss: - print(f" idx_bss = {idx_bss}") - print(f" idx_comment = {idx_comment}") - print(f" idx_shstrtab = {idx_shstrtab}") + print(f" Индексы в .shstrtab: text={idx_text}, data={idx_data}, bss={idx_bss if has_bss else 'N/A'}, comment={idx_comment}, shstrtab={idx_shstrtab}") - # 1. Заголовок для .text (индекс 1) + # 1. .text header_text = struct.pack(' 0: + # SHT_NOBITS = 8, SHF_WRITE|SHF_ALLOC = 3 header_bss = struct.pack('") @@ -639,41 +594,31 @@ def main(): print(f"\n📊 Анализ CSV: {csv_file}") - sections, bss_blocks, max_addr = analyze_csv(csv_file) - has_bss = len(bss_blocks) > 0 - print_section_info(sections, has_bss, max_addr) + sections, bss_blocks, max_addr, bss_total_size, bss_start_vaddr = analyze_csv(csv_file) + has_bss = bss_total_size > 0 + print_section_info(sections, has_bss, max_addr, bss_total_size, bss_start_vaddr) - # Вычисляем смещения (как в kvs_8.py) text_offset = sections['.text']['start'] data_offset = sections['.data']['start'] text_size = sections['.text']['size'] data_size = sections['.data']['size'] - # Размеры данных comment_data = generate_comment_data() comment_size = len(comment_data) - # Порядок размещения (как в kvs_8.py): - # 1. .text (0x1000) - # 2. .data (0x2000) - # 3. .comment (сразу после .data) comment_offset = data_offset + data_size print(f" comment_offset = 0x{comment_offset:x}") - # 4. .shstrtab (выравнивание на 8 байт после .comment) shstrtab_data = generate_shstrtab_binary(has_bss) shstrtab_size = len(shstrtab_data) shstrtab_offset = align_up(comment_offset + comment_size, 8) print(f" shstrtab_offset = 0x{shstrtab_offset:x}") print(f" shstrtab_size = {shstrtab_size}") - # 5. Таблица секций (выравнивание на 16 байт после .shstrtab) - # Количество секций: NULL + .text + .data + .comment + .shstrtab (+ .bss если есть) - num_sections = 5 # NULL + .text + .data + .comment + .shstrtab + num_sections = 5 if has_bss: - num_sections += 1 # + .bss + num_sections += 1 - # Таблица секций размещается после .shstrtab shdr_offset = align_up(shstrtab_offset + shstrtab_size, 16) print(f" shdr_offset = 0x{shdr_offset:x}") @@ -685,33 +630,37 @@ def main(): print(f" Количество секций: {num_sections}") print(f" Наличие BSS: {has_bss}") - # ПЕРЕСОЗДАЁМ ПРОГРАММНЫЕ ЗАГОЛОВКИ - regenerate_program_headers_in_csv(csv_file, sections, has_bss, text_offset, data_offset) + # === НОВЫЙ КОД: обновляем max_addr === + max_addr = max(max_addr, comment_offset + comment_size - 1) + max_addr = max(max_addr, shstrtab_offset + shstrtab_size - 1) + max_addr = max(max_addr, shdr_offset + (num_sections * 64) - 1) + print(f"\n📍 Обновлённый максимальный файловый адрес: 0x{max_addr:08x}") + # === КОНЕЦ НОВОГО КОДА === - # Генерируем записи таблицы секций + # Обновляем программные заголовки с учётом BSS + regenerate_program_headers_in_csv(csv_file, sections, bss_total_size, text_offset, data_offset) + + # Создаём записи таблицы секций entries, num_headers = create_section_table_entries( - sections, has_bss, shdr_offset, shstrtab_offset, comment_offset, comment_size, shstrtab_data + sections, has_bss, shdr_offset, shstrtab_offset, comment_offset, comment_size, + shstrtab_data, bss_start_vaddr, bss_total_size ) - # Генерируем данные для .comment comment_entries = add_comment_data(comment_offset) - - # Генерируем данные для .shstrtab shstrtab_entries = add_shstrtab_data(shstrtab_offset, shstrtab_data) e_shoff = shdr_offset e_shnum = num_headers e_shentsize = 64 + e_shstrndx = num_headers - 1 print(f"\n📝 Обновление ELF-заголовка:") print(f" e_shoff = 0x{e_shoff:08x}") print(f" e_shnum = {e_shnum}") print(f" e_shentsize = {e_shentsize}") + print(f" e_shstrndx = {e_shstrndx}") - # Обновляем ELF-заголовок в CSV - update_elf_header_in_csv(csv_file, e_shoff, e_shnum, e_shentsize) - - # Добавляем таблицу секций, .comment и .shstrtab в CSV + update_elf_header_in_csv(csv_file, e_shoff, e_shnum, e_shentsize, e_shstrndx) merge_csv_with_section_table(csv_file, entries, comment_entries, shstrtab_entries) print(f"\n💾 Таблица секций добавлена в {csv_file}") @@ -723,10 +672,7 @@ def main(): print(f" .shstrtab выровнен на 8 байт") print(f" Таблица секций выровнена на 16 байт") if has_bss: - print(f" BSS присутствует → индекс .shstrtab = 21") - else: - print(f" BSS отсутствует → индекс .shstrtab = 21") - + print(f" BSS присутствует, размер {bss_total_size} байт, адрес 0x{bss_start_vaddr:x}") if __name__ == "__main__": main() \ No newline at end of file diff --git a/todo.txt b/todo.txt index bdbaf88..60daa9c 100644 --- a/todo.txt +++ b/todo.txt @@ -252,3 +252,4 @@ Pass2 (шаг 5): сохранить_байт и загрузить_байт_из_памяти есть в INSTRUCTIONS, но не реализованы в диспетчере encode_instruction +пятый проход добавляет в разнобой свои добавления - адреса идет не по порядку \ No newline at end of file