Error A2006: undefined symbol : base_l - Assembler
Формулировка задачи:
Очередная программа не хочет собираться, материться и всё тут... Неопределённый символ, но эти символы объявлены, в чём проблема, что не нравится MASM32?
Код программы:
error A2006: undefined symbol : base_l
error A2006: undefined symbol : base_m
.486P ;разрешение трансляции всех команд Pentium ;Структура для описания дескрипторов сегментов descr struc ;Начало объявления структуры lim dw 0 ;границы (биты 0...15) base_l dw 0 ;база, биты 0...15 base_m db 0 ;база, биты 1...23 attr_1 db 0 ;байт атрибутов 1 attr_2 db 0 ;граница (биты 16...19) и атрибуты 2 base_h db 0 ;база, биты 24...31 descr ends ;конец объявления структуры data segment use16 ;16 - разрядный сегмент ;Таблица глобальных дескрипторов GDT gdt_null descr <0,0,0,0,0,0> ;селектор 0, нулевой дескриптор gdt_data descr <data_size-1,0,0,92h,0,0> ;селектор 8, сегмент данных gdt_code descr <code_size-1,0,0,98h,0,0> ;селектор 16, сегмент команд gdt_stack descr <255,0,0,92h,0,0> ;селектор 24, сегмент стека gdt_screen descr <3999,8000h,0Bh,92h,0,0> ;селектор 32, видеопамять gdt_size=$-gdt_null ;размер GDT ;Различные данные программы pdescr df 0 ;псевдодескриптор для команды lgdt sym db 1 ;символ для вывода на экран attr db 1Eh ;его атрибут msg db 27,'[31;42m Вернулись в реальный режим! ',27,'[0m$' data_size=$-gdt_null ;размер сегмента данных data ends text segment use16 ;16 - разрядный сегмент команд assume cs:text,ds:data main proc xor eax,eax ;очистим EAX mov ax,data ;загрузим в DS сегментный mov ds,ax ;адрес сегмента данных ;Вычислим 32-битовый линейный адрес сегмента данных и загрузим его ;в дескриптор сегмента данных в таблице глобальных дескрипторов GDT shl eax,4 ;EAX=линейный базовый адрес mov ebp,eax ;сохраним его в EBP для будущего mov bx,offset gdt_data ;BX=смещение дескриптора mov [bx].base_l,ax ;загрузим младшую часть базы shr eax,16 ;старшую половину EAX в AX mov [bx].base_m,al ;загрузим среднюю часть базы ;Вычислим и загрузим в GTD линейный адрес сегмента команд xor eax,eax ;очистим EAX mov ax,cs ;сегментный адрес сегмента команд shl eax,4 ;EAX = линейный базовый адрес mov bx,offset gdt_code ;BX = смещение дескриптора mov [bx].base_l,ax ;загрузим младшую часть базы shr eax,16 ;старшую половину EAX в AX mov [bx].base_m,al ;загрузим среднюю часть базы ;Вычислим и загрузим в GTD линейный адрес сегмента стека xor eax,eax ;очистим EAX mov ax,ss ;сегментный адрес сегмента стека shl eax,4 mov bx,offset gdt_stack ; mov [bx].base_l,ax shr eax,16 mov [bx].base_m,al ;Подготовим псевдодескриптор pdescr и загрузим регистр GDTR mov dword ptr pdescr+2,ebp ;база GDT mov word ptr pdescr,gdt_size-1 ;граница GDT lgdt pdescr ;загрузим регистр GDTR ;Подготовимся к возврату из защищённого режима в реальный mov ax,40h ;настроим ES на область mov es,ax ;данных BIOS mov word ptr es:[67h],offset return ;смещение возврата mov es:[69h],cs ;сегмент возврата mov al,0Fh ;выборка байта состояния отключения out 70h,al ;порт КМОП-микросхемы mov al,0Ah ;установка режима восстановления out 71h,al ;в регистре 0Fh сброса процессора cli ;запрет аппаратных прерываний ;Переход в защищённый режим mov eax,cr0 ;получим содержимое регистра CR0 or eax,1 ;установим бит защищённого режима mov cr0,eax ;запишем назад в CR0 ;------------------------------------------------------------------------- ;Теперь процессор работает в защищённом режиме ;------------------------------------------------------------------------- ;Загружаем в CS:IP селектор:смещение точки continue db 0EAh ;код команды FAT JMP dw offset continue ;смещение dw 16 ;селектор сегмента команд continue: ;Делаем адресуемыми данные mov ax,8 ;селектор сегмента данных mov ds,ax ;настроим DS на селектор данных? ;Делаем адресуемым стек mov ax,24 ;селектор сегмента стека mov ss,ax ;Инициализируем ES mov ax,32 ;селектор сегмента видеобуфера mov es,ax ;инициализируем ES ;Выводим на экран тестовую строку символов mov di,1920 ;начальная позиция на экране mov cx,80 ;число выводимых символов mov ax,word ptr sym ;символ+атрибут scrn: stosw ;содержимое AX на экран inc al ;инкремент кода символа loop scrn ;цикл вывода ;----------------------------------------------------------------- ;Вернёмся в реальный режим ;----------------------------------------------------------------- mov al,0FEh ;команда сброса процессора out 64h,al ;в порт 64h hlt ;Останов процессора до окончания сброса ;--------------------------------------------------------------------- ;Теперь процессор снова работает в реальном режиме ;--------------------------------------------------------------------- return: ;Восстановим вычислительную среду реального режима mov ax,data ;сделаем адресуемыми данные mov ds,ax mov ax,stk ;сделаем адресуемым стек mov ss,ax mov sp,256 ;настроим SP sti ;разрешим аппаратные прерывания ;Работаем в DOS mov ah,09h ;проверим выполнение функции DOS mov dx,offset msg ;после возврата в реальный режим int 21h mov ax,4C00h ;завершим программу обычным образом int 21h main endp code_size=$-main ;размер сегмента команд text ends ;Сегмент стека stk segment stack use16 ;16-разрядный сегмент стека db 256 dup ('^') stk ends end main
Решение задачи: «Error A2006: undefined symbol : base_l»
textual
Листинг программы
struc KNIGA { .prolog dw 0 .ot_avtora dw 0 .glava_1 : dd 0 .glava_2 : db 0 .kartinka dw 0 .epilog dw 0 .soderganie dd 0 };KNIGA ;ends kng KNIGA ; определение "переменной" типа структура mov eax,[kng.ot_avtora]
Объяснение кода листинга программы
- Структура KNIGA объявлена с полями: prolog, ot_avtora, glava_1, glava_2, kartinka, epilog, soderganie.
- Переменная kng типа структура KNIGA определена.
- Значение поля ot_avtora структуры KNIGA сохраняется в регистре eax.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д