Assembler коды ошибок

Logo Море(!) аналитической информации!

Приложение E. Сообщения об ошибках

          В данном приложении описаны все сообщения, генерируемые Тур-
     бо  Ассемблером.  Обычно  сообщения выдаются на экран,  однако их
     можно переадресовать в файл или на принтер с  помощью стандартных
     средств DOS переадресации потоков, т.е. надо указать имя устройс-
     тва или файла с предшествующим ему  символом  "больше  чем"  (>).
     Например:

                     TASM MYFILE > ERRORS

          В Турбо Ассемблере генерируются сообщения следующих типов:

          - информационные сообщения;
          - предупреждающие сообщения;
          - сообщения об ошибках;
          - сообщения о фатальных ошибках.


Информационные сообщения

Турбо Ассемблер обычно выводит два информационных сообщения. Во-первых, всегда выдается информационное сообщение непосредс- твенно перед началом ассемблирования пользовательского исходного файла (или файлов). Кроме того, выдается информационное сообщение по окончании ассемблирования каждого файла. Пример информационно- го сообщения, выдаваемого при запуске Турбо Ассемблера: Turbo Assembler Version 3.0 Copyright(C) 1991 Borland International Assembling file: TEST.ASM (Турбо Ассемблер, версия 3.0, продукт фирмы Borland, 1991г.) По окончании ассемблирования исходного файла выдается сооб- щение с краткой характеристикой процесса ассемблирования. Это со- общение выглядит следующим образом: Error messages: None Warning messages: None Passes: 1 Remaining memory: 279K (Сообщения об ошибках: Нет Проходов: 1 Предупреждающие сообщения: Нет Осталось памяти: 279Кб) Подавить все информационные сообщения можно с помощью пара- метра командной строки /T. Информационные сообщения подавляются только в случае отсутствия ошибок в процессе ассемблирования. При наличии ошибок параметр /T никакого влияния не имеет: стандартные информационные сообщения будут выданы в начале и в конце процесса ассемблирования.

Предупреждающие сообщения и сообщения об ошибках

Предупреждающие сообщения выдаются для информирования поль- зователей о возможных нежелательных последствиях ассемблирования оператора исходного файла. Предупреждающее сообщение выдается, например, в тех случаях, когда использование Turbo Assembler ка- кого-либо, вообще говоря, допустимого умолчания может привести к некорректным результатам. Рекомендуется обязательно проанализиро- вать причины предупреждающих сообщений, чтобы не допустить гене- рации неверного кода. Наличие этих сообщений не влияет на генера- цию объектного кода Turbo Assembler. Предупреждающие сообщения имеют следующий формат: **Warning** имя_файла(номер_строки) сообщение Если предупреждающее сообщение выдается во время расширения макрокоманды или блока повторения, то оно будет содержать допол- нительную информацию: имя макрокоманды и номер строки, при ас- семблировании которой возникло это сообщение. Предупреждающее со- общение в этом случае имеет следующий формат: **Warning** имя_файла(номер_строки) имя_макрокоманды(номер_строки_в_макрокоманде)сообщение В отличие от предупреждающих сообщений, появление сообщений об ошибках означает, что объектный код Турбо Ассемблер генериро- вать не будет, хотя процесс ассемблирования будет доведен до кон- ца. Типичное сообщение об ошибке имеет следующий формат: **Error** имя_файла(номер_строки) сообщение Если сообщение об ошибке выдается во время расширения макро- са или блока повтора, то оно будет содержать дополнительную ин- формацию: имя макрокоманды и номер строки, при ассемблировании которой возникло это сообщение. Сообщение об ошибке в этом случае имеет следующий формат: **Error** имя_файла(номер_строки) имя_макрокоманды(номер_строки_в_макрокоманде)сообщение Далее в алфавитном порядке приводятся тексты предупредитель- ных сообщений и сообщений об ошибках:

32-bit segment not allowed without .386

(32-битовые флаги без директивы .386 не допускаются) Это средство расширено. Теперь в операторе .MODEL можно за- давать USE32 и LARGESTACK. Ранее это было сообщение "USE32 not allowed without .386").

Argument needs type override

(Требуется явно указать тип операнда) Требуется явно указать размер, или тип, выражения, т.к. он не может быть определен из контекста. Например, ошибочной являет- ся следующая команда: mov [bx],1 Ошибки такого рода обычно корректируются с помощью операции PTR, позволяющей установить размер операнда: mov WORD PTR[bx],1

Argument to operation or instruction has illegal size

(Операнд операции или команды имеет недопустимый размер) В операции указан операнд, имеющий тип, недопустимый для данной операции. Например: Q LABEL QWORD QNOT = NOT Q ; операнд операции отрицания не может ; иметь тип QWORD

Arithmetic overflow

(Арифметическое переполнение) Потеря значащих цифр при вычислении значения выражения. Нап- ример: X = 20000h * 20000h ; результат занимает более 32 бит Точность всех арифметических операций - 32 бита.

ASSUME must be segment register

(В директиве ASSUME должен быть указан сегментный регистр) В директиве ASSUME можно указывать только сегментные регист- ры, во всех остальных случаях выводится данное сообщение об ошиб- ке. Например, ошибочной является директива: ASSUME ax:CODE

Bad keyword in SEGMENT statement

(Неверное ключевое слово в операторе SEGMENT) Один из параметров директивы SEGMENT: тип выравнивания, тип объединения или тип сегмента имеет недопустимое значение. Напри- мер: DATA SEGMENT PAFA PUBLIC ; вместо PARA указано PAFA

Can't add relative quantities

(Нельзя складывать относительные адреса) Выражение содержит операцию сложения двух адресов, что явля- ется бессмысленной операцией. Например: ABC DB ? DEF = ABC + ABC ; ошибка: нельзя складывать ; два относительные адреса Можно вычитать относительные адреса. Можно добавить констан- ту к относительному адресу, например: XYZ DB 5 DUP(0) XYZEND EQU $ XYZLEN = SYZEND - XYZ ; совершенно верно XYZ2 = XYZ + 2 ; тоже верно

Can't address with currently ASSUMEd segment registers

(Невозможна адресация из текущих, установленных директивой ASSUME, сегментных регистров) В выражении содержится ссылка на переменную, для доступа к которой не специфицирован сегментный регистр. Например: DSEG SEGMENT ASSUME ds:DSEG mov si,MPTR ; не определен сегментный регистр, который ; обеспечил бы доступ к сегменту XSEG DSEG ENDS XSEG SEGMENT MPTR DW ? XSEG ENDS

Can't convert to pointer

(Невозможно преобразование в указатель) Часть выражения не может быть преобразована в указатель на память, например, с помощью операции PTR: mov cl,[BYTE PTR al] ; AL нельзя преобразовать ; в указатель

Can't emulate 8087 instruction

(Невозможна эмуляция команд сопроцессора 8087) В Турбо Ассемблере параметром командной строки /E либо с по- мощью директивы EMUL установлен режим генерации эмулированных ко- манд арифметики с плавающей точкой, однако текущая команда не мо- жет быть эмулирована. Например: EMUL FNSAVE [WPTR] ; эта команда не может быть эмулирована Некоторые команды не поддерживаются эмуляторами арифметики с плавающей точкой. Это команды FNSAVE, FNSTCW, FNSTENV и FNSTSW.

Can't make variable public

(Переменная не может быть объявлена как PUBLIC) Переменная была уже ранее объявлена таким образом, что уже не может быть определена как общая (PUBLIC). Например: EXTRN ABC:NEAR PUBLIC ABC ; ошибка: ABC уже ранее объявлена ; с атрибутом EXTRN

Can't override ES segment

(Нельзя переопределить сегмент ES) В текущем операторе указан регистр, использование которого в данной команде недопустимо. Например: STOS DS:BYTE PTR[di] В команде STOS для определения целевого адреса допускается использовать только регистр ES.

Can't subtract dissimilar relative quantities

(Недопустимое вычитание относительных адресов) Выражение содержит операцию вычитания двух адресов, которая для данных адресов является недопустимой. Данное сообщение выда- ется, например, в том случае, если адреса находятся в разных сег- ментах. Например: SEG1 SEGMENT A: SEG1 ENDS SEG2 SEGMENT B: mov ax,B-A ; недопустимо, поскольку A и В находятся ; в разных сегментах SEG2 ENDS

Can't use macro name in expression

(Недопустимо использование имени макрокоманды в качестве операнда выражения) Имя макрокоманды указано в качестве операнда выражения. Нап- ример: MyMac MACRO ENDM mov ax,MyMac ; ошибка!

Can't use this outside macro

(Использование данного оператора недопустимо вне макроопре- деления) Вне макроопределения указана директива, которую допускается использовать только внутри макроопределений. К таким директивам относятся, например, ENDM и EXITM. Например: DATA SEGMENT ENDM ; ошибка: вне макроопределения недопустимо

Code or data emission to undeclared segment

(Не объявлен сегмент для кода или данных) Оператор, генерирующий код или данные, не принадлежит ни од- ному из сегментов, объявленных директивами SEGMENT. Например: ; Первая строка файла inc bx ; ошибка: не определен сегмент END Генерировать данные или код можно только внутри какого-либо сегмента.

Constant assumed to mean Immediate const

(Константа интерпретируется как непосредственная) Это предупреждающе сообщение выдается для выражений типа [0]. В режиме MASM это выражение интерпретируется как непосредс- твенная константа, равная 0. Например: mov ax,[0]; означает mov ax,0, а не mov ax,ds:[0]

Constant too large

(Слишком большая константа) Константа имеет, вообще говоря, правильный формат, однако ее значение превышает допустимую для данного режима величину. Напри- мер, числа, большие 0ffffh, можно использовать, если только ди- рективой .386/.386P или .486/.486Р разрешены команды процессора 386 или i486.

CS not correctly assumed

(Некорректное значение в регистре CS) Адрес назначения в командах ближнего вызова и ближнего пере- хода не может находиться в другом сегменте. Например: SEG1 SEGMENT LAB1 LABEL NEAR SEG1 ENDS SEG2 SEGMENT JMP LAB1 ; ошибка: неверный сегментный адрес SEG2 ENDS Такие ошибки возникают только в режиме MASM. В режиме Ideal такие переходы и вызовы интерпретируются корректно.

CS override in protected mode

(Переопределение регистра CS в защищенном режиме) В защищенном режиме ассемблирования команд процессора 286, 386 или i486, установленном директивой Р286Р, P386P или Р486Р, в текущей команде требуется переопределение регистра CS. Например: P286 .CODE CVAL DW ? mov CVAL,1 ; генерирует переопределение регистра CS Это предупреждающее сообщение выдается, если в командной строке указан параметр /Р. В защищенном режиме команды, в которых переопределяется регистр CS, не будут выполняться без специальных подготовительных операций.

CS unreachable from current segment

(CS недостижим из текущего сегмента) При определении метки кода с помощью двоеточия (:) или с по- мощью директив LABEL или PROC сегментный регистр не указывает на текущий кодовый сегмент или группу, содержащую текущий кодовый сегмент. Например: PROG1 SEGMENT ASSUME CS:PROG2 START: ; ошибка: неверно установлен регистр CS Такие ошибки возникают только в режиме MASM. В режиме Ideal такие переходы и вызовы обрабатываются корректно.

Declaration needs name

(В директиве объявления не указано имя) Не указано имя идентификатора в директиве, для которой спе- цификация имени является обязательной. Например: PROC ; ошибка: в директиве PROC указание имени обязательно ret ENDP В директивах объявления, таких как SEGMENT, PROC или STRUC, обязательно должно быть указано имя идентификатора. В режиме MASM имя указывается перед именем директивы, а в режиме Ideal - после имени директивы.

Directive ignored in Turbo Pascal model

(В режиме TPASCAL директива игнорируется) В модуле Ассемблера, предназначенном для интерфейса с Турбо Паскалем, используется недопустимая директива. Режим интерфейса с Турбо Паскалем специфицируется директивой .MODEL. Более подробно интерфейс с Турбо Паскалем обсуждается в Главе 19.

Directive not allowed inside structure definition

(Недопустимая директива внутри определения структуры) Внутри блока определения структуры указана недопустимая ди- ректива. Например: X STRUC MEM1 DB ? ORG $+4 ; ошибка: директиву ORG нельзя указывать ; внутри структуры MEM2 DW ? ENDS При определении вложенных структур нельзя определять новые структуры на внутренних уровнях. Например: F00 STRUC F002 STRUC ; ошибка: определена новая структура ENDS ENDS Для того чтобы использовать одну структуру внутри другой структуры, нужно сначала определить первую структуру, а после этого во второй структуре можно указывать имя первой.

Duplicate dummy arguments:_

(Недопустимо использование одинаковых имен для формальных параметров) В директиве MACRO определено несколько формальных параметров с одинаковыми именами. Например: XYZ MACRO A,A ; ошибка: дублируются имена ; формальных параметров DB A ENDM Все формальные параметры макроопределения должны иметь раз- личные имена.

ELSE or ENDIF without IF

(ELSE или ENDIF без IF) Для директивы ELSE или ENDIF нет парной директивы IF, обоз- начающей начало условно ассемблируемого блока. Например: BUF DB 10 DUP(?) ENDIF ; ошибка: нет парной директивы IFxxx

Expecting METHOD keyword

(Требуется ключевое слово METHOD) В расширенном структурном операторе для определения объектов после порождающего объекта требуется ключевое слово METHOD.

Expecting offset quantity

(Требуется указать величину смещения) В качестве операнда выражения указано неверное значение вместо ожидаемого смещения внутри сегмента. Например: CODE SEGMENT mov ax,LOW CODE CODE ENDS

Expecting offset or pointer quantity

(Требуется указать смещение или указатель) В качестве операнда выражения указано неверное значение вместо ожидаемого смещения внутри специфицированного сегмента. Например: CODE SEGMENT mov ax,SEG CODE ; ошибка: СODE - это сегмент, ; а не адрес внутри сегмента CODE ENDS

Expecting pointer type

(Операнд должен быть указателем) Операндом текущей команды должен быть адрес памяти. Напри- мер: LES di,4 ; неверно, т.к. 4 - константа

Expecting record field name

(Требуется имя поля записи) Вы использовали инструкцию SETFIELD или GETFIELD без после- дующего имени поля.

Expecting register ID

(Требуется идентификатор регистра) В части USES оператору CALL.METHOD требуются имена регист- ров.

Expecting scalar type

(Операнд должен быть константой) Операндом текущей команды должна быть константа. Например: BB DB 4 rol ax,BB ; ошибка: вторым операндом операции ROL ; должна быть константа

Expecting segment or group quantity

(Должно быть указано имя сегмента или группы) В операторе вместо имени сегмента или группы указано имя, которое таковым не является. Например: DATA SEGMENT ASSUME ds:F00 ; ошибка: F00 не является именем ; сегмента или группы F00 DW 0 DATA ENDS

Extra characters on line

(Лишние символы в строке) Выражение имеет корректный синтаксис, однако вслед за ним, на той же строке имеются еще лишние символы. Например: ABC = 4 shl 3 3 ; нет знака операции ; между двумя тройками Данная ошибка обычно является следствием другой ошибки, в результате которой анализатор выражений преждевременно заканчива- ет обработку выражения.

Forward reference needs override

(Ошибка при использовании умолчания для ссылки вперед) В результате использования умолчания для ссылки вперед было зарезервировано меньше памяти, чем это оказалось необходимо. Эта ошибка возникает тогда, когда имя идентификатора, по умолчанию означающее адрес ближнего перехода или вызова, переопределяется в программе как дальний адрес. Эта ошибка возникает также в тех случаях, когда не указан сегмент (отличный от предполагаемого по умолчанию) для доступа к переменной. Например: ASSUME cs:DATA call A ; по умолчанию - ближний вызов A PROC FAR ; а здесь переопределяется как дальний mov ax,MEMVAR ; не известно, что требуется другой сегмент DATA SEGMENT MEMVAR DW ? ; здесь ошибка: требуется переопределение Эти ошибки исправляются путем явного указания сегмента или типа перехода FAR.

Global type doesn't match symbol type

(Тип, указанный в директиве GLOBAL не совпадает с действи- тельным типом имени идентификатора) Это предупреждающее сообщение выдается, если объявление сим- волического имени директивой GLOBAL находится в том же самом сег- менте, где определяется это имя идентификатора, однако тип, ука- занный в директиве GLOBAL, не совпадает с действительным типом этого имени идентификатора.

ID not member of structure

(Идентификатор не является полем структуры) В режиме Ideal после точки (селектора поля структуры) указа- но имя идентификатора, которое не является именем поля структуры. Например: IDEAL STRUC DEMO DB ? ENDS COUNT DW 0 mov ax,[(DEMO bx).COUNT] ; COUNT не является ; полем структуры После точки может быть указано только имя поля той структу- ры, имя которой указано перед точкой. Данная ошибка обычно является следствием другой ошибки, в результате которой анализатор выражений преждевременно заканчива- ет обработку выражения.

Illegal forward reference

(Недопустимая ссылка вперед) Имя идентификатора, на которое происходит ссылка, еще не бы- ло определено, а в соответствующей директиве не допускается ис- пользовать ссылки вперед. Например: IF MYSYM ; ошибка: MYSYM еще не определена ; ENDIF MYSYM EQU 1 Ссылки вперед нельзя использовать в директивах вида IFxxx, а также в качестве счетчика выражений в операции DUP.

Illegal immediate

(Недопустим непосредственный операнд) Команда содержит непосредственный операнд (т.е. константу) там, где он недопустим. Например: mov 4,al

Illegal indexing mode

(Недопустимый режим индексации) Команда содержит операнд, использующий недопустимую комбина- цию регистров. Например: mov al,[si+ax] Для всех процессоров, за исключением 80386, допустимыми ком- бинациями индексных регистров являются следующие: BX, BP, SI, DI, BX+SI, BX+DI, BP+SI, BP+DI.

Illegal instruction

(Недопустимая команда) Строка исходной программы начинается с имени идентификатора, которое не является ни именем директивы, ни мнемоникой команды. Например: move ax,4 ; должно быть "MOV"

Illegal instruction for currently selected processor(s)

(Недопустимая команда для выбранного в настоящий момент про- цессора (процессоров)) Строка программы содержит команду, которая не может быть ас- семблирована текущим процессором. Например: .8086 PUSH 1234h ; занесение в стек непосредственного ; операнда для процессора 8086 не ; допускается При ассемблировании исходного файла с помощью Турбо Ассемб- лера по умолчанию будут разрешены команды процессора 8086. Если желательно использовать расширенные мнемоники команд, определен- ные для процессоров 186/286/386, то должна быть указана одна из директив, разрешающих использование этих команд (Р186, Р286, Р386).

Illegal local argument

(Недопустимый локальный параметр) В директиве LOCAL внутри макроопределения указан параметр, не являющийся допустимым именем идентификатора. Например: X MACRO LOCAL 123 ; это не идентификатор ENDM

Illegal local symbol prefix

(Недопустимый префикс для локальных имен идентификаторов) В директиве LOCALS специфицируется недопустимый префикс для локальных имен идентификаторов. Например: LOCALS XYZ ; ошибка: допускается только 2 символа Префикс локальных идентификаторов должен состоять ровно из двух символов и представлять собой допустимое имя идентификатора. Например, допустимыми являются следующие комбинации: __, @@ (по умолчанию для локальных имен идентификаторов используется префикс @ @).

Illegal mаcro argument

(Недопустимый параметр макрокоманды) В директиве MACRO для формального параметра макрокоманды указано недопустимое имя идентификатора. Например: X MACRO 123 ; недопустимый формальный параметр ENDM

Illegal memory reference

(Недопустима ссылка на память) Операнд команды содержит ссылку на адрес памяти, что недо- пустимо для данного операнда. Например: mov [bx],BYTE PTR A ; ошибка: недопустима пересылка ; из памяти в память В данной команде оба операнда представляют собой адреса па- мяти, что недопустимо в команде mov. В командах семейства процес- соров 80х86 только один из операндов может ссылаться на адрес па- мяти.

Illegal number

(Недопустимое число) Число содержит один или более символов, недопустимых для чи- сел данного формата. Например: Z = 0ABCGH Здесь G - недопустимый символ для шестнадцатиричных чисел.

Illegal origin address

(Недопустимый начальный адрес) Указан адрес, недопустимый для установки текущего сегментно- го адреса ($). Допускается указывать константу, выражение, ис- пользующее счетчика адреса ($), или имя идентификатора из текуще- го сегмента.

Illegal override in structure

(Недопустимое переопределение в структуре) Попытка инициализировать элемент структуры, определенный с помощью операции DUP. Инициализировать можно только те члены, ко- торые были объявлены без использования операции DUP.

Illegal override register

(Недопустимое переопределение регистра) В ссылке на сегмент перед двоеточием был указан регистр, не являющийся сегментным регистром. К сегментным регистрам относятся следующие регистры: CS, DS, ES, SS, а также FS и GS для процессо- ра 80386. Например: mov dx:XYZ,1 ; DX не является сегментным регистром

Illegal radix

(Недопустимое основание системы счисления) В директиве .RADIX в качестве основания системы счисления указано недопустимое число. Например: .RADIX 7 ; неверно Основанием системы счисления могут быть следующие числа: 2, 8, 10 и 16. Это число интерпретируется как десятичное, независимо от текущего умолчания для основания системы счисления.

Illegal register for instruction

(Недопустимый регистр в инструкции) В качестве источника в инструкции SETFIELD и GETFIELD ис- пользован недопустимый регистр.

Illegal register multiplier

(Недопустимо указание множителя для регистра) Попытка умножить регистр на какое-либо число, что является недопустимой операцией. Например: mov ax * 3,1 Единственный случай, когда допускается умножение регистра на константное выражение - это при определении масштабного индексно- го операнда для процессора 80386.

Illegal segment address

(Недопустимый сегментный адрес) Это сообщение об ошибке выдается, если для позиционирования сегмента указывается значение адреса, превышающее 65535. Напри- мер: F00 SEGMENT AT 12345h

Illegal use of constant

(Недопустимо использование константы) В выражении используется константа там, где использование константы недопустимо. Например: mov bx+4,5

Illegal use of register

(Недопустимо использование регистра) В выражении указывается имя регистра там, где использование регистра недопустимо. Например: X = 4 shl ax ; в операции SHL нельзя указывать регистры

Illegal use of segment register

(Недопустимо использование сегментного регистра) В выражении или команде указывается имя сегментного регистра там, где использование сегментного регистра недопустимо. Напри- мер: ADD SS,4 ; в команде ADD нельзя указывать ; сегментные регистры

Illegal USES register

(В директиве USES указан недопустимый регистр) Указан недопустимый регистр в командах PUSH и POP при входе и выходе из процедуры. Допустимы следующие регистры: AX CX DS ES BX DI DX SI Если директивой .386 или .386Р разрешены команды процессора 80386, то можно указывать 32-битовые эквиваленты перечисленных выше сегментов.

Illegal version ID

(Недопустимый идентификатор версии) Эта ошибка происходит, когда в параметре /U или в операторе VERSION выбирается недопустимая версия.

Illegal warning ID

(Недопустимый идентификатор предупреждающего сообщения) Введен неверный трехсимвольный идентификатор предупреждающе- го сообщения. Список всех допустимых идентификаторов предупрежда- ющих сообщений приведен в Главе 2.

Instruction can be compacted with override

(Возможно сокращение длины команды, если явно указать тип имени) Из-за наличия ссылки вперед на имя идентификатора генерируе- мый код содержит дополнительные команды NOP. Для того чтобы сок- ратить код можно убрать ссылку вперед либо явно указать тип сим- волического имени. Например: jmp X ; для этой команды будет выдано предупреждающее ; сообщение jmp SHORT X ; не будет выдано предупреждающего сообщения Х:

Invalid model type

(Недопустимая модель памяти) В директиве .MODEL для модели памяти указано недопустимое ключевое слово. Например: .Model GIGANTIC Для обозначения моделей памяти допустимы следующие ключевые слова: TINY, SMALL, COMPACT, MEDIUM, LARGE и HUGE.

Invalid operand(s) to instruction

(Недопустимый операнд(ы) для данной команды) В команде указана недопустимая комбинация операндов. Напри- мер: FADD ST(2), ST(3) В команде FADD только на один стековый регистр можно ссы- латься по имени, другой операнд должен быть вершиной стека.

Labels can't start with numeric characters

(Метки не могут начинаться с цифровых символов) Обнаружено имя, которое не является ни допустимым числом, ни допустимым именем идентификатора. Например: 123XYZ.

Line too long - truncated

(Строка слишком длинная - производится усечение) Текущая строка исходного файла содержит более 255 символов. Лишние символы игнорируются.

Location counter overflow

(Переполнение счетчика адреса) Текущий сегмент заполнен, последующий код или данные затрут начало сегмента. Например: ORG 0FFF0h ARRAY DW 20 DUP (0) ; переполнение

Method call requires object name

(В вызове метода необходимо имя объекта) Оператор CALL.METHOD не может получить тип объекта из эк- земпляра указателя. Вы должны указать имя объекта.

Missing argument list

(Отсутствует список аргументов) В директиве IRP или IRPC, определяющей блок повторения, не указан список аргументов для формального параметра. Например: IRP X ; нет списка аргументов DB X ENDM В директивах IRP и IRPC обязательно должен быть указан фор- мальный параметр и список аргументов.

Missing argument or <

(Отсутствует аргумент, либо не указана угловая скобка <) Не указаны угловые скобки, либо вообще отсутствует выражение в угловых скобках там, где оно необходимо. Например: if b ; должно быть указано выражение в угловых ; скобках

Missing argument size variable

(Отсутствует переменная для размера блока параметров) В директиве ARG или LOCAL не указано имя идентификатора пос- ле знака равенства в конце оператора. Например: ARG A:WORD,B:DWORD= ; ошибка, нет имени после знака= LOCAL X:TBYTE= ; та же ошибка В директивах ARG и LOCAL после знака равенства, если он ука- зан, обязательно должно быть указано имя переменной для размера блока параметров.

Missing COMM ID

(Отсутствует идентификатор в директиве COMM) В директиве COMM не указано имя идентификатора перед специ- фикатором типа. Например: COMM NEAR ; ошибка: отсутствует ; имя идентификатора перед "NEAR" В директиве СОММ обязательно должно быть указано имя иденти- фикатора. Имя идентификатора и спецификатор типа должны быть раз- делены двоеточием (:).

Missing dummy argument

(Отсутствует формальный параметр) В директиве IRP или IRPC, определяющей блок повтора, отсутс- твует формальный параметр. Например: IRP DB X ; нет формального параметра ENDM В директивах IRP и IRPC обязательно должны быть указаны фор- мальный параметр и список аргументов.

Missing end quote

(Отсутствует закрывающая кавычка) В конце строковой константы нет закрывающей кавычки. Напри- мер: DB "abc ; отсутствует кавычка в конце ABC mov al,'X ; отсутствует кавычка после Х Строковая константа должна оканчиваться той же кавычкой, ко- торой она начинается.

Missing macro ID

(Отсутствует идентификатор макрокоманды) В директиве MACRO, определяющей макрокоманду, отсутствует имя. Например: MACRO ; ошибка: не указано имя макрокоманды DB A ENDM Имя в определении макрокоманды указывать обязательно.

Missing module name

(Отсутствует имя модуля) В директиве NAME не указано имя модуля. Напомним, что дирек- тива NAME действует только в режиме Ideal.

Missing or illegal language ID

(Отсутствует или неверно указан идентификатор языка) В директиве .MODEL неверно указан идентификатор языка. Под- робное описание директивы MODEL см. в Главе 7 настоящего руко- водства.

Missing or illegal type specifier

(Отсутствует или неверно указан спецификатор типа) В операторе отсутствует или неверно указан обязательный па- раметр - идентификатор типа (BYTE, WORD и т.д.) Например: RED LABEL XXX ; ошибка: "ХХХ" не является ; идентификатором типа

Missing table member ID

(Пропущен идентификатор элемента таблицы) В операторе CALL.METHOD после ключевого слова METHOD пропущено имя объекта.

Missing term in list

(Отсутствует член в списке параметров) В режиме Ideal в директиве, допускающей указание нескольких параметров (такой как EXTRN, PUBLIC и т.д.), отсутствует параметр после одной из запятых, отделяющих параметры друг от друга. Нап- ример: EXTRN XXX:BYTE,,YYY:WORD В режиме Ideal параметры в любом списке всегда разделяются только одной запятой, в конце списка запятой быть не должно.

Missing text macro

(Отсутствует текстовая макрокоманда) В директиве не указан обязательный параметр - текстовая мак- рокоманда. Например: NEWSTR SUBSTR ; для SUBSTR должны быть ; указаны параметры

Model must be specified first

(Сначала должна быть указана модель памяти) Использована одна из упрощенных сегментных директив без предварительной спецификации модели памяти. Например: .CODE ; ошибка: сначала нужно указать директиву ; .MODEL Перед использованием упрощенных сегментных директив должна быть указана с помощью директивы .MODEL модель памяти.

Module is pass-dependant - compatibility pass was done

(Модуль зависит от прохода. Выполнен проход, обеспечивающий совместимость с MASM) Это предупреждающее сообщение выдается, если обнаружена конструкция, зависящая от прохода, и в командной строке указан параметр /m. В этом случае выполняется проход, обеспечивающий совместимость с MASM.

Name must come first

(Имя должно быть указано первым) Имя идентификатора указано после названия директивы, тогда когда оно должно находиться перед названием директивы. Например: STRUC ABC ; ошибка: "ABC" должно стоять перед ; ключевым словом STRUC В режиме Ideal имя идентификатора указывается после названия директивы, поэтому эта ошибка часто возникает при попытках ас- семблирования в режиме MASM программ, предназначенных для работы в режиме Ideal.

Near jump or call to different CS

(Адресат ближнего перехода или вызова находится в другом ко- довом сегменте) Это сообщение об ошибке выдается при попытке осуществить ближний вызов или переход по адресу, определенному в области, где регистр CS указывает на другой сегмент.

Need address or register

(Требуется указать адрес или регистр) Не указан второй операнд команды, т.е. операнд указываемый после запятой. Например: mov ax, ; нет второго операнда

Need angle brackets for structure fill

(Значения для структуры должны указываться в угловых скоб- ках) В операторе выделения памяти под структуру не указан список начальных значений. Например: STR1 STRUC M1 DW ? M2 DD ? ENDS STR1 ; нет списка начальных значений

Need colon

(Требуется двоеточие) В директиве EXTRN, GLOBAL, ARG и LOCAL отсутствует двоеточие перед спецификатором типа (BYTE, WORD и т.д.) Например: EXTRN X BYTE,Y:WORD ; после Х нет двоеточия

Need expression

(Требуется указать выражение) Выражение содержит операцию, для которой не указан операнд. Например: Х = 4 + * 6

Need file name after INCLUDE

(В директиве INCLUDE должно быть указано имя файла) В директиве INCLUDE не указано имя файла. Например: INCLUDE ; не указано, какой файл должен быть включен В режиме Ideal имя файла должно быть заключено в кавычки.

Need left parenthesis

(Отсутствует левая круглая скобка) Опущена левая круглая скобка там, где это не допускается синтаксисом выражения. Например: DB 4 DUP 7 Выражение в операции DUP обязательно должно быть заключено в круглые скобки.

Need method name

(Требуется имя метода) Оператор CALL.METHOD требует после ключевого слова METHOD имени метода.

Need pointer expression

(Требуется выражение-указатель) Эта ошибка возникает только в режиме Ideal и указывает, что выражение в квадратных скобках ([]) не является указателем на па- мять. Например: mov ax,[word ptr] В режиме Ideal в квадратных скобках допускается указывать только адресные выражения.

Need quoted string

(Требуется указать строку в кавычках) Ошибка при вводе параметра директивы, который должен предс- тавлять собой строку, заключенную в кавычки. В режиме Ideal для ряда директив в качестве параметра указывается строка в кавычках. Например: Ideal DISPLAY "Все сделано"

Need register in expression

(В выражении требуется указать имя регистра) В выражении не указано имя регистра там, где это является обязательным.

Need right angle bracket

(Отсутствует правая угловая скобка) Выражение, используемое для инициализации структуры, объеди- нения или записи, не оканчивается правой угловой скобкой (>) - парной для левой угловой скобки, указывающей начало списка на- чальных значений. Например: MYSTRUC STRUCNAME <1,2,3

Need right curly bracket

(Требуется правая фигурная скобка) Эта ошибка возникает в структуре, таблице или записи, когда ожидается }, но она не найдена.

Need right parenthesis

(Отсутствует правая круглая скобка) Выражение содержит левую круглую скобку без парной ей правой угловой скобки. Например: Х = 5 * (4 + 3 В выражениях обязательно должно соблюдаться соответствие ле- вых и правых круглых скобок.

Need right square bracket

(Отсутствует правая квадратная скобка) Выражение, представляющее собой ссылку на память, указано без правой квадратной скобки, которая должна соответствовать отк- рывающей левой квадратной скобке, обозначающей начало выражения. Например: mov ax,[SI ; ошибка: нет закрывающей ; скобки (]) после SI В выражениях обязательно должно соблюдаться соответствие ле- вых и правых квадратных скобок.

Need stack argument

(Не указан стековый параметр) В команде арифметики с плавающей запятой не указан второй операнд, т.е. операнд, указываемый после запятой. Например: FADD ST,

Need structure member name

(Не указано имя поля структуры) В режиме Ideal после селектора поля структуры (т.е. после точки) не указано имя поля этой структуры. Например: Ideal STRUC DEMO DB ? ENDS COUNT DW 0 mov,[(DEMO bx).] При обращении к полю структуры справа от точки обязательно должно быть указано поле той структуры, имя которой стоит слева от точки.

Not expecting group or segment quantity

(Использование имени группы или сегмента недопустимо) Указано имя группы или сегмента там, где это недопустимо. Например: CODE SEGMENT rol ax,CODE ; ошибка: здесь нельзя указывать ; имя сегмента

One non-null field allowed per union expansion

(При расширении объединения допускается указывать только од- но поле непустым) При инициализации объединения, определенного директивой UNION, указано более одного значения. Например: U UNION DW ? DD ? ENDS UINST U <1,2> ;ошибка: можно указать <?,2> либо <1,?> В объединении можно инициализировать только одно поле.

Only one startup sequence allowed

(Допускается только одна директива генерации кода инициали- зации) Это сообщение выдается, если в модуле указано более одной директивы .STARTUP или STARTUPCODE.

Open conditional

(Открытый условный блок) Обнаружена директива END, означающая конец исходного файла. Однако условно ассемблируемый блок, открытый одной из директив вида IFxxx, не был закрыт директивой ENDIF. Например: IF BIGBUF END ; нет директивы ENDIF перед директивой END Эта ошибка обычно выдается, если вместо директивы окончания условного блока ENDIF, ошибочно указана директива END.

Open procedure

(Открытая процедура) Обнаружена директива END, означающая конец исходного файла. Однако блок описания процедуры, открытый директивой PROC, не был закрыт директивой ENDР. Например: MYFUNC PROC END ; нет директивы ENDР перед директивой END Эта ошибка обычно выдается, если вместо директивы конца бло- ка процедуры - ENDP ошибочно указана директива END.

Open segment

(Открытый сегмент) Обнаружена директива END, означающая конец исходного файла. Однако сегмент, открытый директивой SEGMENT, не был закрыт дирек- тивой ENDS. Например: DATA SEGMENT END ; нет директивы ENDS перед директивой END Эта ошибка обычно выдается, если вместо директивы конца сег- мента - ENDS ошибочно указана директива END.

Open structure definition

(Не указан конец определения структуры) Обнаружена директива END, означающая конец исходного файла. Однако определение структуры, начало которой указано директивой STRUCTURE, не было завершено директивой ENDS. Например: X STRUC VAL1 DW ? END ; нет директивы ENDS перед директивой END Эта ошибка обычно выводится, если вместо директивы конца структуры ENDS ошибочно указана директива END.

Operand types do not match

(Не совпадают типы операндов) Тип одного из операндов команды не совпадает с типом другого операнда либо не является допустимым для данной команды. Напри- мер: ABC DB 5 . mov ax,ABC

Operation illegal for static table member

(Для статического элемента таблицы операция не допускается) Для получения адреса статического элемента таблицы использо- вана операция точки. Это не допускается.

Pass-dependant construction encountered

(Обнаружена конструкция, зависящая от прохода) Действие оператора возможно не совпадает с ожидаемым из-за однопроходности Турбо Ассемблера. Например: IF1 ; на шаге ассемблирования ENDIF IF2 ; на шаге листинга ENDIF Большинство конструкций, с которыми связано это сообщение, может быть скорректировано так, чтобы это сообщение исчезло. Обычно для этого достаточно убрать ссылки вперед.

Pointer expression needs brackets

(Адресное выражение должно быть заключено в квадратные скоб- ки) В режиме Ideal операнд, содержащий имя идентификатора, представляющее собой ссылку на память, не заключен в квадратные скобки. В режиме Ideal квадратные скобки означают ссылку на адрес памяти. Например: B DB 0 mov al,B ; предупреждение: в режиме Ideal ; должно быть указано [B] Т.к. в режиме MASM квадратные скобки не обязательны, то это сообщение выдается как предупреждающее.

Positive count expecting

(Счетчик должен быть положительным) В выражении для DUP в качестве счетчика повторений указано отрицательное число. Например: BUF -1 DUP (?) ; ошибка: отрицательный счетчик Счетчик в операции DUP должен быть равен или больше 1.

Record field too large

(Слишком длинное поле в записи) В определении записи сумма длин всех полей превышает 32 би- та. Например: AREC RECORD RANGE:12,TOP:12,BOTTOM:12

Record member not found

(Не найден статический элемент записи) Элемент записи задан в заполнителе указанной записи, который не является частью заданной записи.

Recursive definition not allowed for EQU

(Рекурсивное определение не допустимо в директиве EQU) В выражении директивы EQU содержится то же самое имя, кото- рое определяется этой директивой. Например: ABC EQU TWOTIMES ABC

Register must be AL or AX

(Допустимо указание только регистра AL или AX) Неверен операнд команды. Допускается использовать только ре- гистры AL и AX. Например: IN CL,dx ; ошибка: в первом операнде команды IN ; допускается указывать только регистры AL и AX

Register must be DX

(Допустимо указание только регистра DX) Неверен операнд команды. Допускается использовать только ре- гистр DX. Например: IN AL,cx ; ошибка: вместо СХ должен быть указан регистр DX

Relative jump out of range by __ bytes

(Адрес назначения условного перехода превышает допустимый предел на __ байт) Адрес назначения в команде условного перехода находится вне допустимого диапазона, т.е. не принадлежит интервалу (-127, +128) от текущего адреса. В 32-битовом сегменте адрес назначения услов- ного перехода должен находиться в диапазоне от -32767 до +32768 байт от текущего адреса.

Relative quantity illegal

(Недопустимый относительный адрес) Команда или директива содержит операнд, ссылающийся на адрес памяти таким способом, что эта ссылка не может быть разрешена на этапе ассемблирования. Такие ссылки в Турбо Ассемблере являются недопустимыми. Например: DATA SEGMENT PUBLIC X DB 0 IF OFFSET X GT 127 ; на этапе ассемблирования ; адрес не известен

Reserved word used as symbol

(Зарезервированное слово используется в качестве имени иден- тификатора) В программе пользователя определяется имя идентификатора, совпадающее с одним из зарезервированных слов Турбо Ассемблера. Программа будет ассемблироваться правильно, однако переопределять зарезервированные в Турбо Ассемблере слова не рекомендуется.

Rotate count must be constant or CL

(Счетчик в командах сдвига должен быть указан с помощью константы или регистра CL) В команде сдвига или циклического сдвига указан операнд, от- личный от константы и регистра CL. Например: ROL ax,DL ; ошибка: регистр DL нельзя указывать ; в качестве счетчика В командах сдвига и циклического сдвига в качестве второго операнда можно указывать только константу или регистр CL.

Rotate count out of range

(Недопустимое значение для счетчика сдвига) В команде сдвига или циклического сдвига второй операнд пре- вышает допустимое значение. Например: .8086 SHL DL,3 ; ошибка: в командах процессора 8086 ; возможен сдвиг только на один разряд .286 ROR ax,40 ; ошибка: максимальное допустимое ; значение для счетчика сдвига равно 31 Максимальное допустимое значение для счетчика сдвига в ко- мандах процессора 8086 равно 1, для других процессоров это значе- ние может быть равно 31.

Segment alignment not strict enough

(Выравнивание сегмента не достаточно точное) Указано недопустимое значение для границы выравнивания сег- мента. Либо оно не является степенью двойки, либо специфицирует более точное выравнивание чем то, которое указано в директиве SEGMENT. Например: DATA SEGMENT PARA ALIGN 32 ; ошибка: PARA означает только 16 ALIGN 3 ; ошибка: не является степенью двойки

Segment attributes illegally redefined

(Недопустимое переопределение атрибутов сегмента) Директивой SEGMENT повторно открывается уже определенный ра- нее сегмент, при этом указываются новые значения для атрибутов этого сегмента. Например: DATA SEGMENT BYTE PUBLIC DATA ENDS DATA SEGMENT PARA ; ошибка: ранее было указано ; выравнивание на байт DATA ENDS При повторном открытии сегмента атрибуты либо должны иметь те же самые значения, либо вообще быть опущены. Если при повтор- ном открытии сегмента атрибуты не указаны, то используются атри- буты из предыдущего определения.

Segment name is superfluous

(Имя сегмента игнорируется) Это предупреждающее сообщение выдается в тех случаях, когда в директиве .CODE указано имя сегмента, а в текущей модели памяти не допускается использовать более одного сегмента.

String too long

(Слишком длинная строка) Указанная в кавычках строка имеет длину, превышающую макси- мально допустимую - 255 символов.

Symbol already defined:__

(Имя идентификатора уже определено) Указанное имя идентификатора уже было ранее объявлено с тем же самым типом. Например: BB DB 1,2,3 BB DB ? ; ошибка: BB уже определено

Symbol already different kind

(Имя идентификатора уже объявлено с другим типом) Указанное идентификатора имя было ранее объявлено с другим типом, например: BB DB 1,2,3 BB DW ? ; ошибка: BB уже объявлено с типом BYTE

Symbol has no width or mask

(Имя идентификатора не может быть использовано в операциях WIDTH и MASK) Операнд операции WIDTH или MASK не является именем записи или именем поля записи. Например: B DB 0 mov ax,MASK B ; В не является полем записи

Symbol is not a segment or already part of a group

(Имя идентификатора не является именем сегмента либо уже оп- ределено в группе) Либо имя идентификатора уже определено в группе, либо не яв- ляется именем сегмента. Например: DATA SEGMENT DATA ENDS DGROUP GROUP DATA DGROUP2 GROUP DATA ; ошибка: DATA уже определено в DGROUP

Text macro expansion exceeds maximum line length

(Расширение текстовой макрокоманды превышает максимально до- пустимую длину) Это сообщение об ошибке выдается, когда расширение текстовой макрокоманды превышает максимально допустимую длину.

Too few operands to instruction

(В команде не хватает операндов) В команде должно быть указано большее число операндов. Нап- ример: ADD ax ; отсутствует второй операнд

Too many errors or warnings

(Слишком много ошибок или предупреждений) Сообщения об ошибках больше выдаваться не будут. Максималь- ное число сообщений об ошибках, которое выдается Турбо Ассембле- ром, равно 100. Это максимально допустимое число ошибок превыше- но. Ассемблирование программы тем не менее будет продолжено, однако далее будут печататься только предупреждающие сообщения.

Too many initial values

(Слишком много начальных значений) При инициализации структуры или объединения указано слишком много значений. Например: XYZ STRUC A1 DB ? A2 DB ? XYZ ENDS ANXYZ XYZ <1,2,3> ; ошибка: в XYZ определены ; только два поля При инициализации полей структур и объединений допускается указывать меньше значений, чем число полей, но нельзя указывать больше значений.

Too many register multipliers in expression

(В выражении содержится слишком много множителей для регист- ров) Для процессора 80386 допускается коэффициент индексных опе- рандов. Однако коэффициент можно указывать не более, чем у одного регистра. Например: mov EAX,[2*EBX+4*EDX] ; слишком много ; коэффициентов

Too many registers in expression

(В выражении указано слишком много регистров) В выражении указано более одного индексного и одного базис- ного регистра. Например: mov ax,[BP+SI+DI] ; нельзя одновременно указывать SI и DI

Too many USES registers

(Слишком много регистров в директиве USES) В директиве USES для текущей процедуры указано более 8 ре- гистров.

Trailling null value assumed

(Предполагается конечное пустое значение) Директива определения данных (DB, DW и т.д.) оканчивается запятой. TASM интерпретирует ее как пустое значение. Например: db 'привет',13,10 ; то же, что и db'привет',13,10?

Undefined symbol

(Идентификатор не определен) Оператор содержит идентификатор, который не был ранее опре- делен в исходном файле.

Unexpected end of file (no END directive)

(Неожиданный конец файла (нет директивы END)) В исходном файле отсутствует директива END. Директива END обязательно должна быть указана в конце исходного файла.

Unknown character

(Неизвестный символ) Текущая строка исходной программы содержит символ, который не принадлежит набору символов, допустимых для построения симво- лических имен и выражений в Турбо Ассемблере. Например: add ax,!1 ; ошибка: восклицательный знак - ; недопустимый символ

Unmatched ENDP:_

(Непарная директива ENDP:_) В директиве ENDP указано имя, не совпадающее с именем проце- дуры, которую закрывает данная директива. Например: ABC PROC XYZ ENDP ; ошибка: вместо XYZ должно быть указано ABC

Unmatched ENDS:_

(Непарная директива ENDS:_) В директиве ENDS указано имя, не совпадающее с именем сег- мента, который закрывает данная директива, либо не совпадающее с именем структуры или объединения, оканчивающегося этой директи- вой. Например: ABC STRUC XYZ ENDP ; ошибка: вместо XYZ должно быть указано ABC DATA SEGMENT CODE ENDS ; ошибка: вместо CODE должно быть указано DATA

User-generated error

(Ошибка, сгенерированная пользователем) Ошибка выдана в результате выполнения одной из директив ге- нерирования ошибки. Например: .ERR ; попадание в это место является ошибкой USES has no effect without language (USES игнорируется без спецификации языка) Это предупреждающее сообщение выдается, если оператор USES используется без предварительной спецификации языка.

Value out of range

(Значение константы превышает допустимое значение) Константа представляет собой, вообще говоря, число правиль- ного формата. Однако ее значение превышает допустимую в данном конкретном случае величину. Например: DB 400

Сообщения о фатальных ошибках -----------------------------------------------------------------

При возникновении фатальных ошибок Турбо Ассемблер выдает соответствующее сообщение и ассемблирование пользовательского файла немедленно прекращается, независимо от того чем была вызва- на эта ошибка. В этом разделе приводится перечень возможных сооб- щений о фатальных ошибках.

Bad switch

(Неверный параметр-переключатель командной строки) В командной строке указан неверный параметр. См. Главу 2, где дается подробное описание параметров командной строки.

Can't find @file __

(Не найден файл подсказок __) В командной строке указано имя несуществующего файла подска- зок. Следует проверить, указано ли полное имя файла. В Турбо Ас- семблере отсутствует умолчание для расширения имени файла подска- зок. Вероятной причиной данного сообщения может быть отсутствие места на диске при записи на этот диск файла, содержащего перек- рестные ссылки.

Сan't locate file __

(Не обнаружен файл __) В директиве INCLUDE указано имя несуществующего файла. О ди- рективе INCLUDE см. Главу 10 настоящего руководства, где описан алгоритм поиска Турбо Ассемблером включаемых файлов. Если выдано это сообщение, проверьте, правильно ли указано в имени файла имя дисковода и маршрут доступа.

Error writing to listing file

(Ошибка при записи в файл листинга) Возможно при записи файла листинга на диск было исчерпано место на этом диске.

Error writing to object file

(Ошибка при записи в объектный файл) Возможно при записи объектного файла на диск было исчерпано место на этом диске.

File not found

(Не найден файл) В командной строке указано имя несуществующего исходного файла. Проверьте, правильно ли указано имя файла, включены ли имя диска и маршрут доступа, если файл находится в каталоге, отличном от текущего.

File was changed or deleted while assembly in progress

(Файл был изменен или уничтожен в процессе ассемблирования) Какая-либо другая программа, например, резидентная активизи- руемая утилита, уничтожила открытый Турбо Ассемблером файл. В Турбо Ассемблере не допускается повторное открытие файла, который был ранее успешно открыт.

Insufficient memory to process command line

(Не хватает памяти для обработки командной строки) Командная строка занимает более 64К, либо для ее обработки не хватает имеющейся памяти. Следует упростить командную строку либо запустить Турбо Ассемблер при наличии большего объема памя- ти.

Internal error

(Внутренняя ошибка) Это сообщение не должно выдаваться при нормальной работе Турбо Ассемблера. Сделайте копию файлов, вызвавших появление этой ошибки, и сообщите в отдел технического обслуживания фирмы Borland.

Invalid command line

(Недопустимая командная строка) Неверен формат командной строки, с помощью которой запуска- ется Турбо Ассемблер. Например, в команде: NASM, MYFILE не указан исходный файл, который должен ассемблироваться. См. Главу 2, где дается подробное описание командной строки.

Invalid number after _

(Недопустимый номер после _) Верно указан идентификатор параметра, однако неверно специ- фицирован числовой параметр после нее. См. Главу 2, где описаны параметры командной строки.

Out of hash space

(Не хватает памяти под хеш-таблицы) Каждому имени идентификатора, определяемому в пользователь- ской программе, соответствует один элемент хеш-таблицы. Эта таб- лица рассчитана на 16384 определяемых пользователем имен иденти- фикаторов при условии запуска Турбо Ассемблера с достаточным объ- емом свободной памяти. Если в программе пользователя определено большее количество имен идентификаторов, то нужно указать пара- метр командной строки /КН, для того чтобы обеспечить в хеш-табли- це нужное число элементов для описания этого количества символи- ческих имен.

Out of memory

(Не хватает памяти) Не хватает свободной памяти для ассемблирования пользова- тельского файла. Попробуйте использовать TASMX. Если в оперативной памяти имеются какие-либо резидентные в памяти программы, то следует убрать их и повторить ассемблирова- ние файла. Возможно, что потребуется перезагрузить систему, для того чтобы полностью освободить память. Другой путь состоит в том, чтобы разбить исходный файл на два или более, или переписать части исходного файла таким обра- зом, чтобы его ассемблирование требовало меньше памяти. Для этого в программе следует укоротить имена идентификаторов, уменьшить число комментариев в макрокомандах, уменьшить число ссылок впе- ред.

Out of string space

(Не хватает памяти под строки) Не хватает оперативной памяти для хранения строк: имен иден- тификаторов, имен файлов, информации для разрешения опережающих ссылок, текстов макрокоманд. Допускается максимум 512К памяти, а ваш модуль превысил этот объем. Попробуйте использовать TASMX.

Too many errors found

(Обнаружено слишком много ошибок) Ассемблирование пользовательского файла прекращено, посколь- ку в этом файле содержится слишком много ошибок. Возможно, что на самом деле ошибок не так уж и много, однако они таковы, что вызы- вают эффект "снежного кома". Примером такой ошибки может быть не- верное определение имени идентификатора, которое используется во многих строках программы. На самом деле сделана лишь одна ошибка (неверно определено имя идентификатора), однако сообщение об ошибке будет выдано в каждой строке, где появляется это имя. Турбо Ассемблер прекращает ассемблирование файла, когда об- щее число ошибок и предупреждающих сообщений достигает 100.

Unexpected end of file (no END directive)

(Неожиданный конец файла (отсутствует директива END)) В конце исходного файла отсутствует директива END. Каждый исходный файл обязательно должен заканчиваться директивой END.
                       Назад | Содержание | Вперед


Обратная связь
Информация для авторов

Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum

Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее…

Assembler Warnings

MPASM assembler warnings are listed numerically below:

201 Symbol not previously defined.

Symbol being #undefined was not previously defined.

202 Argument out of range. Least significant bits used.

Argument did not fit in the allocated space. For example, literals must be 8 bits.

203 Found opcode in column 1.

An opcode was found in column one, which is reserved for labels.

204 Found pseudo-op in column 1.

A pseudo-op was found in column one, which is reserved for labels.

205 Found directive in column 1.

A directive was found in column one, which is reserved for labels.

206 Found call to macro in column 1.

A macro call was found in column one, which is reserved for labels.

207 Found label after column 1.

A label was found after column one, which is often due to a misspelled opcode.

208 Label truncated at 32 characters.

Maximum label length is 32 characters.

209 Missing quote.

A text string or character was missing a quote. For example, DATA ‘a.

210 Extra ),

An extra comma was found at the end of the line.

211 Extraneous arguments on the line.

Extra arguments were found on the line. These warnings should be investigated, since they are often indications of the free-format parser interpreting something in a manner other than was intended (try assembling OPTION EQU 0x81 with LIST FREE).

212 Expected

Expected a certain type of argument. A description should be provided. For the warning, an assumption is made about the argument.

213 The EXTERN directive should only be used when making a .o file.

The EXTERN directive only has meaning if an object file is being created. This warning has been superseded by Error 149.

214 Unmatched (

An unmatched parenthesis was found. The warning is used if the parenthesis is not used for indicating order of evaluation.

215 Processor superseded by command line. Verify processor symbol.

The processor was specified on the command line as well as in the source file. The command line has precedence.

216 Radix superseded by command line.

The radix was specified on the command line as well as in the source file. The command line has precedence.

217 Hex file format specified on command line.

The hex file format was specified on the command line as well as in the source file. The command line has precedence.

218 Expected DEC, OCT, HEX. Will use HEX.

Bad radix specification.

219 Invalid RAM location specified.

If the _ _MAXRAM and _ _BADRAM directives are used, this warning flags use of any RAM locations declared as invalid by these directives. Note that the provided header files include _ _MAXRAM and _ _BADRAM for each processor.

220 Address exceeds maximum range for this processor.

A ROM location was specified that exceeds the processor’s memory size.

221 Invalid message number.

The message number specified for displaying or hiding is not a valid message number.

222 Error messages cannot be disabled.

Error messages cannot be disabled with the ERRORLEVEL command.

223 Redefining processor

The selected processor is being reselected by the LIST or PROCESSOR directive.

224 Use of this instruction is not recommended.

Use of the TRIS and OPTION instructions is not recommended for a PIC16CXXX device.

225 Invalid label in operand.

Operand was not a valid address. For example, if the user tried to issue a CALL to a MACRO name.

226 UNKNOWN WARNING

A warning has occurred which the assembler cannot understand. It is not any of the warnings described in this appendix. Contact your Microchip Field Application Engineer (FAE) if you cannot debug this warning.

Добавил:

Upload

Опубликованный материал нарушает ваши авторские права? Сообщите нам.

Вуз:

Предмет:

Файл:

Скачиваний:

212

Добавлен:

14.03.2016

Размер:

6.05 Mб

Скачать

Ассемблер на примерах. Базовый курс

В результате получим файл msgbox.obj, который нужно передать компонов­ щику alink:

С:\WIN32>ALINK -оРЕ msgbox

Параметры -о определяет тип исполняемого файла. Родным для Windows является тип РЕ. После компоновки появится файл msgbox.exe, который можно будет запустить.

11.3. Программная совместимость

Для процессора, работающего в защищенном режиме, доступен другой специ­ альный режим — VM86, обеспечивающий эмуляцию реального режима. Все привилегированные команды (то есть сИ, popf и др.), а также все обращения к периферийным устройствам (команды in и out) перехватываются и эмулиру­ ются ядром операционной системы так, что прикладной программе «кажется», что она действительно управляет компьютером. На самом же деле все вызовы функций DOS и BIOS обрабатываются ядром операционной системы.

11.4. Запуск DOS-приложений под Windows

Для запуска DOS~пpилoжeния в среде Windows мы используем так называ­ емый «Сеанс MS DOS». Для запуска DOS-режима выполните команду cmd (Пуск -^ Выполнить -> cmd). Открывшееся окно работает в режиме VM86 и полностью эмулирует функции DOS. Если файлы компилятора NASM на­ ходятся в каталоге C:\NASM, мы можем использовать команду DOS, чтобы перейти в этот каталог:

cd С:\NASM

Помните, что в DOS существует ограничение на длину файлов — все имена файлов должны быть в формате 8+3 (8 символов — имя, 3 — расширение). Для редактирования исходных файлов используйте редактор, который по­ казывает номера строк — так будет прош;е найти ошибку. Избегайте также «слишком дружественных» приложений, которые добавляют расширение «.txt» после расширения «.asm».

11.5. Свободные источники информации

Мы рекомендуем следующие источники, посвященные программированию на языке ассемблера в Windows:

http://win32asm.cjb.net http://rsl .szif.hu/~tomcat/win32

http://asm.shadrinsk.net/toolbar.html

190

Глава 1 Программирование в Linux

Структура памяти процесса

Передача параметров командной строки и переменных окружения

Вызов операционной системы

Коды ошибок

Облегчим себе работу: утилиты

Asmutils. Макросы Asmutils

Отладка. Отладчик ALD

Ассемблер GAS

Ключи командной строки компилятора

12.1. Введение

Linux — современная многозадачная операционная система. Большая часть ядра Linux написана на С, но небольшая его часть (аппаратно-зависимая) на­ писана на языке ассемблера. Благодаря портируемости языка С Linux быстро распространилась за пределы х86-процессоров. Ведь для переноса ядра на другую аппаратную платформу разработчикам пришлось переписать только ту самую маленькую часть, которая написана на ассемблере.

Как любая другая современная многозадачная система, Linux строго разде­ ляет индивидуальные процессы. Это означает, что ни один процесс не может изменить ни другой процесс, ни тем более ядро, вследствие чего сбой одного приложения не отразится ни на других приложениях, ни на операционной системе.

В х86-совместимых компьютерах процессы в памяти защищены так называ­ емым защищенным режимом процессора. Этот режим позволяет контроли­ ровать действия программы: доступ программы к памяти и периферийным устройствам ограничен правами доступа. Механизмы защиты разделены между ядром операционной системы (которому разрешается делать абсолютно все)

ипроцессами (им можно выполнять только непривилегированные команды

изаписывать данные только в свою область памяти).

Защищенный режим также поддерживает виртуальную память. Ядро опе­ рационной системы предоставляет все операции для работы с виртуальной памятью. Кроме, конечно, трансляции логических адресов в физические — эта функция выполняется «железом» (см. главу 8).

Благодаря виртуальной памяти (и, конечно же, 32-битным регистрам), любой процесс в Linux может адресовать 4 Гб адресного пространства. Именно 4 Гб и выделены каждому процессу. Что имеется в виду? Если сделать дамп памяти от О до самого конца (4 Гб), вы не обнаружите ни кода другого процесса, ни данных другого процесса, ни кода ядра — 4 Гб полностью предоставлены в ваше распоряжение. Ясно, что реальный объем виртуальной памяти будет зависеть от физической памяти и от объема раздела подкачки, но суть в том, что процессы скрыты друг от друга и друг другу не мешают.

192

Глава 12. Программирование в Linux

12.2. Структура памяти процесса

Мы уже знаем, что нам доступны все 4 Гб и ни один процесс не может втор­ гнуться в наше адресное пространство. Как же распределена память нашего процесса? Как было сказано в предыдущих главах, программа состоит из че­ тырех секций: секция кода, секция статических данных, секция динамических данных (куча) и стек. Порядок, в котором загружаются эти секции в память, определяется форматом исполняемого файла. Linux поддерживает несколь­ ко форматов, но самым популярным является формат ELF (Executable and Linkable Format). Рассмотрим структуру адресного пространства ELF-файла. Предположим для простоты, что программа не использует динамических библиотек.

Адрес:

0x08048000

.text

Исполняемый код

.data

Статические данные (известны во время компиляции)

.bss

Динамические данные (так называемая куча)

Свободная память

.stack

Стек

OxBFFFFFFF (3 Гб)

Обычно программа загружается с адреса 0x08048000 (примерно 128 Мб). При загрузке программы загружается только одна ее страница. Остальные страни­ цы загружаются по мере необходимости (неиспользуемые части программы никогда физически не хранятся в памяти).

На диске программа хранится без секций .bss и .stack — эти секции появля­ ются только тогда, когда программа загружается в память.

Если программа подключает какие-нибудь динамические библиотеки, их модули загружаются в ее адресное пространство, но начинаются с другого адреса (обычно с 1 Гб и выше). Секции этих модулей аналогичны секциям обычной программы (то есть .text, .data, .bss).

А что хранится в трехгигабайтном «зазоре» между .bss и .stack, то есть в сво­ бодной памяти? Эта память принадлежит процессу, но она не распределена по страницам. Запись в эту область вызовет сбой страницы (page fault) — после этого ядро уничтожит вашу программу.

Для создания динамических переменных вам нужно попросить ядро распре­ делить соответствующую память, но об это мы поговорим чуть позже.

193

Ассемблер на примерах. Базовый курс

12.3. Передача параметров командной строки и переменных окружения

Если процессы полностью изолированы друг от друга, то как нам получить параметры командной строки и переменные окружения? Ведь они — собствен­ ность другого процесса — оболочки, запустившей нашу программу. Решили эту проблему очень просто: при запуске программы параметры командной строки и переменные окружения помещаются в стек программы. А поскольку стек нашей программы — это наша собственность, мы можем без проблем получить к нему доступ. Рассмотрим структуру стека:

ESP после запуска программы

Свободная память

1

argc

Количество параметров (dword)

argv[0]

Указатель на имя программы

argv[1]

Указатели на аргументы программы

argv[argc-1]

NULL

Конец аргументов командной строки

|

env[0]

env[1]

Указатели на переменные окружения

env[n]

[

NULL

Конец переменных окружения

Нужный аргумент легко вытолкнуть из стека по команде POP, а потом запи­ сать в какую-нибудь переменную. Первое значение, которое мы получим из стека — это количество аргументов командной строки (argc), второй — ука­ затель на имя нашей программы.

Если argc > 1, значит, программа была запуш^ена с аргументами и дальше в стеке находятся они.

Примеры обработки аргументов командной строки будут рассмотрены после того, как вы научитесь выводить данные на экран.

12.4. Вызов операционной системы

Вызвать функции операционной системы DOS можно было с помощью пре­ рывания 0x21. В Linux используется похожий метод: прерывание с номером 0x80. Но как мы можем с помощью прерывания добраться до ядра, если оно находится за пределами нашего адресного пространства? Благодаря защищен­ ному режиму, при вызове прерывания 0x80 изменяется контекст программы (значение сегментного регистра) и процессор начинает выполнять код ядра. После завершения обработки прерывания будет продолжено выполнение нашей программы.

194

Глава 12. Программирование в Linux

Подобно DOS, аргументы отдельных системных вызовов (syscalls) передаются через регистры процессора, что обеспечивает небольшой выигрыш в скорости. Номер системного вызова помеш;ается в регистр ЕАХ. Если системный вызов принимает аргументы, то он ожидает их в регистрах ЕВХ, ЕСХ и т.д. По со­ глашению для передачи аргументов служит набор регистров в фиксированном порядке: ЕВХ, ЕСХ, EDX, ESI и EDI. Ядро версии 2.4.x и выше допускает также передачу аргумента через регистр ЕВР.

12.5. К о д ы о ш и б о к

Возвращаемое системным вызовом значение заносится в ЕАХ. Это код ошибки, определяющий состояние завершения системного вызова, то есть уточняющий причину ошибки. Код ошибки всегда отрицательный. В про­ грамме на языке ассемблера, как правило, достаточно отличать успешное завершение от ошибочного, но в ходе отладки значение кода ошибки может помочь выяснить ее причину.

Справочная система Linux содержит man-страницы, описывающие каждый системный вызов вместе с кодами, значениями и причинами всех ошибок, которые он может вернуть.

12.6.Мап-страницы

вотличие от DOS и Windows ОС Linux полностью документирована. В ее спра­ вочной системе (которая называется Manual Pages — Страницы Руководства) вы найдете исчерпывающие сведения не только обо всех установленных про­ граммах, но и обо всех системных вызовах Linux. Конечно, для эффективного использования man-страниц (как и остальной Linux-документации) вам придetcя выучить английский, поскольку далеко не все man-страницы переведены на русский язык. Достаточно уметь читать руководства хотя бы со словарем.

Предположим, что мы хотим написать простейшую программку, которая завершает свою работу сразу после запуска. В DOS нам нужно было ис­ пользовать системный вызов АН=0х4С. Помните? Теперь давайте напишем подобную программку под Linux. Для этого найдите файл unistd.h, который обычно находится в каталоге /usr/src/linux/include/asm:

# i f n d ef

_ASM_I3 8 6_UNISTD_H_

#define

_ASM_I3 8 6_UNISTD_H_

/*

* This

f i l e c o n t a i n s

t h e system c a l l numbers.

V

#define

,NR_exit

1

#define

NR_fork

2

195

Ассемблер на примерах. Базовый курс

#define

NR_read

3

#define

NR_write

4

#define

NR_open

5

#define

NR_close

б

#define _syscalll(type,name,typel,argl) \

type name(typel

argl) \

{ \

long res; \

(«int

$0x80» \

asm

volatile

: «=a»

(

res) \

: «0» {

NR_##name), «b» ((long)(argl))); \

syscall_return(type,

res); \

}

В этом файле вы найдете номера системных вызовов Linux. Нас интересует вызов NR_exit:

Это значит, что функция ядра, завершающая процесс, имеет номер I. Описания функций ядра (системных вызовов) собраны в секции 2 справочного руководства. Посмотрим, что там сказано о функции exit(). Для этого введите команду:

man 2 exit

Вы увидите содержимое man-страницы:

_ЕХ1Т(2)

Linux Programmer’s Manual

_EXIT(2)

NAME

_exit, _Exit — terminate the current process SYNOPSIS

#include <unistd.h> void _exit(int status); #include <stdlib.h> void _Exit(int status); DESCRIPTION

The function _exit terminates the calling process «immedi­ ately». Any open file descriptors belonging to the process are closed; any children of the process are inherited by process 1, init, and the process’s parent is sent a SIGCHLD signal. The value status is returned to the

parent process as the process’s exit status, and can be col­ lected using one of the wait family of calls. The function

_Exit is equivalent to _exit. RETURN VALUE

These functions do not return.

196

Глава 12. Программирование в Linux

Системному вызову ‘exit’ нужно передать всего один параметр (как в DOS) — код возврата (ошибки) программы. Код О соответствует нормальному завер­ шению программы.

Код нашего «терминатора» будет выглядеть так:

mov

е а х Д

; номер

системного вызова

— e x i t

mov

ebx,0

;код возврата О

i n t

0x80

/ВЫЗОВ

ядра и завершение

текущей программы

12-7. Программа «Hello, World!» под Linux

Давайте немного усложним нашу программу — пусть она выведет заветную фразу

изавершит работу. Вспомните, что в главе 8 говорилось о файловых дескрипторах стандартных потоков — ввода (STDIN, обычно клавиатура), вывода (STDOUT, обычно экран) и ошибок (STDERR, обычно экран). Наша программа «Hello, World!» должна вывести текст на устройство стандартного вывода STDOUT

изавершиться. С точки зрения операционной системы STDOUT — это файл, следовательно, мы должны записать нашу строку в файл.

Снова заглянув в unistd.h, находим системный вызов write(). Смотрим его описание:

man 2 w r i t e

WRITE(2)

WRITE(2)

Linux Programmer’s Manual

NAME

write — write to a file descriptor

SYNOPSIS

#include

<unistd.h>

ssize_t w r i t e ( i n t fd, const void *buf,

size_t count);

Если вы не знаете С, то данная шап-страница, скорее всего, для вас будет не­ понятна. Как передать аргументы системному вызову? В языке ассемблера вы можете загрузить в регистр либо непосредственное значение, либо значение какого-то адреса памяти. Для простоты будем считать, что для аргументов, не отмеченных звездочкой, нужно указывать непосредственные значения, а аргументы со звездочкой требуют указателя.

Функции write нужно передать три аргумента: дескриптор файла, указатель на строку, данные из которой будут записаны в файл (это buf), и количество байтов этой строки, которые нужно записать. Функция возвратит количество успешно записанных байтов или отрицательное число, которое будет кодом ошибки.

Для компилирования нашей программы в объектный файл будем использовать nasm, а для компоновки — компоновщик Id, который есть в любой версии

197

Ассемблер на примерах. Базовый курс

Linux. Для получения объектного файла в формате ELF нужно использовать опцию компилятора -f elf.

Компоновщик Id обычно вызывается с ключами, перечисленными в табл. 12. L

Наиболее часто используемые ключи компоновщика Id

Таблица 12.1

Ключ

Назначение

-o<name>

Установить имя выходного (исполняемого) файла <name>

-S

Удалить символьную информацию из файла

Чтобы компоновщик Id определил точку входа программы, мы должны ис­ пользовать глобальную метку _start.

Код нашей программы «Hello, World!» приведен в листинге 12.1.

Листинг 12.1. Программа ЖеПо^World!» под УПУХ

SECTION .text

;указываем компоновщику точку входа.

global _start

_start:

;это сделать необходимо

;первый аргумент — номер системного

mov eax,4

mov ebx,1

;вызова — write

;константа STDOUT определена как 1

mov

ecx,hello

;адрес выводимой строки

mov

edx,len

;длина «Hello, World!» вместе с символом

int 0x80

;конца строки

;вызываем ядро для вывода строки

mov eax,1

;системный вызов номер 1 — exit

mov ebx,0

;код завершения программы О

программы

int 0x80

;вызываем ядро для завершения

SECTION .data

символ

hello db «Hello, world!»,Оха /наша строка плюс

len equ $ — hello

;конца строки

;вычисляем длину строки

Теперь откомпилируем программу:

nasm -f elf hello.asm

A теперь запустим компоновщик:

Id -s -о hello hello.о

Ключ -о определяет имя результирующего исполняемого файла. Ключ -s

удаляет символьную информацию из исполняемого файла, чтобы уменьшить его размер.

198

Глава 12. Программирование в Linux

Теперь осталось запустить программу:

./hello Hello, World!

12.8. Облегчим себе работу; утилиты Asmutils

Asmutils — это коллекция системных программ, написанных на языке ас­ семблера. Эти программы работают непосредственно с ядром операционной системы и не требуют библиотеки LIBC.

Asmutils — идеальное решение для небольших встроенных систем или для «спасательного» диска.

Программы написаны на ассемблере NASM и совместимы с х86-процессорами. Благодаря набору макросов, представляющих системные вызовы, Asmutils легко портируется на другие операционные системы (нужно модифицировать только конфигурационный файл). Поддерживаются следующие операционные системы: BSD (FreeBSD, OpenBSD, NetBSD), UnixWare, Solaris и AtheOS.

Для каждой операционной системы Asmutils определяет свой набор симво­ лических констант и макросов, побочным эффектом которых оказывается улучшение читабельности ассемблерных программ.

В листинге 12.2 можно увидеть, как будет выглядеть наша программа hello с использованием Asmutils.

. |у.рдщцдд~д^^^^

шттшттшшшттттжттшшшшттттщщт

u^xxv^^^de «s_^ stem, ^nc»

CODESEG

;начало секции кода

START:

;начало программы для

sys_write

;компоновщика

STDOUT,helloДen

;этот макрос записывает в регистры

;аргументы для системного вызова write

sys_exit О

;и вызывает write

;то же самое для системного вызова exit

DATASEG

;начало секции данных

hello db «Hello, World!»,Оха len equ $-hello

END

199

Соседние файлы в папке Новая папка_2

  • #

    14.03.2016698 б4Program5.pas101

  • #

    14.03.20161.14 Кб3Program5.pas101new

  • #

    14.03.20161.19 Кб3Program5.pas101new1

  • #

    14.03.2016502 б3Program51.pas

  • #

    14.03.2016692 б3Program511.pas

  • #

Понравилась статья? Поделить с друзьями:
  • Assassins creed valhalla ошибка установки
  • Assassins creed 2 код ошибки 2 как решить
  • Assassins creed brotherhood ошибка ubisoft game launcher
  • Assassins creed black flag ошибка 0xc000007b
  • Assassins creed 4 black flag msvcr100 dll ошибка