Синтаксическая ошибка asm

I had this code and I was wondering if anyone would be willing to help me get it working.

TITLE MASM Template                     (main.asm)

; Description: this code is supposed to print out each letter followed by a space and then the capitalized version on seperate lines
; Revision date:

INCLUDE Irvine32.inc
.data

myArray byte 'l','s','d','t','h','c','f','u','c','k'    ;my array of 10 characters
.code
main PROC

    mov ecx,0                                        ;clears ecx
    mov ecx,LENGTHOF myArray                         ;should be 10
    mov edi,OFFSET myArray                   ;will point to the beginning of the array
    mov eax,0                                       ;clears eax
    mov esi,0                                       ;clears esi

LOne:

    mov eax,myArray[esi]          ;points the pointer at the beginning of myArray
    WriteChar eax                     ;prints the designated value in the array
    WriteChar 32                    ;prints a space (32 is the ascii value for ' ')
    sub eax,32                      ;subtracts 32 from the ascii value of the char
                         ;the capital version of each letter is -32 of its ascii value
    WriteChar eax           ;prints the capital version
    call CLRF               ;prints new line
    inc esi                 ;increments esi to the next array value
    dec ecx                 ;decrements ecx, moving it through the array

    loop LOne               ;loops back until ecx is equal to zero

    exit
main ENDP

END main

It won’t compile giving me syntax errors.

1>main.asm(22): error A2008: syntax error : eax
1>main.asm(23): error A2008: syntax error : WriteChar
1>main.asm(26): error A2008: syntax error : eax
1>main.asm(21): error A2022: instruction operands must be the same size
1>main.asm(27): error A2006: undefined symbol : CLRF

An assembler is just a funny kind of compiler. It accepts a language (called the «assembly language» that it defines for the CPU it supports), and produces binary output for the assembled instructions.

Like other compilers, when it encounters a syntax error, it produces a diagnostic. If it is good, it points out where the syntax error is precisely, but I’ve seen assemblers that simply tell you which line is wrong (with maybe a hint about the error, e.g., «bad opcode»). That’s not different than what lousy compilers do.

After generating the diagnostic, it often chooses some default semantic action (like generating no binary data), and continues onto the next bit of source code.

Just like a regular compiler.

The binary output of most compilers in the face of an error is usually useless; errors tend to cascade in the semantics and produce inappropriate code if it produces code at all. (Many compilers simply stop emitting code when the first error is reported). The binary output of an assembler in the face of an error… may still be useful. Normally the error only affects a small part of the generated binary code.

ДЕСАНТУРА

6 / 6 / 5

Регистрация: 25.02.2015

Сообщений: 202

1

07.09.2015, 21:50. Показов 1628. Ответов 5

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Updater{
 
public:
DWORD baseAddress;
 
};
 
class System {
 
public:
    It* getIt() {
 
        __asm {
 
                mov eax, updater->baseAddress
                call eax
                retn
        }
    }
 
};

Почему ругается на команду

Assembler
1
mov eax, updater->baseAddress
C++
1
2
Серьезность  Код  Описание    Проект    Файл    Строка
Ошибка    C2400   синтаксическая ошибка во встроенном коде на языке ассемблера в "второй операнд"; обнаружено "bad token"

если сделать так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class System {
 
public:
    It* getIt() {
 
DWORD i = updater->baseAddress;
        __asm {
 
                mov eax, i
                call eax
                retn
        }
    }
 
};

То все в порядке.



0



Эксперт С++

4984 / 3091 / 456

Регистрация: 10.11.2010

Сообщений: 11,169

Записей в блоге: 10

07.09.2015, 22:06

2

Потому что в ассемблерной вставке так делать нельзя.
Ассемблерная вставка представляет собой особый синтаксис, а ты пытаешься внутри неё использовать синтаксис языка C++.



1



ДЕСАНТУРА

6 / 6 / 5

Регистрация: 25.02.2015

Сообщений: 202

07.09.2015, 22:23

 [ТС]

3

Цитата
Сообщение от castaway
Посмотреть сообщение

Потому что в ассемблерной вставке так делать нельзя.
Ассемблерная вставка представляет собой особый синтаксис, а ты пытаешься внутри неё использовать синтаксис языка C++.

Дело в том если сделаю класс типо Updater updater и вызову переменную через точку в ассемблерной вставке

C++
1
updater.baseAddress

все работает и особому синтаксису на это чхать с высокой колокольни!



0



Эксперт С++

4984 / 3091 / 456

Регистрация: 10.11.2010

Сообщений: 11,169

Записей в блоге: 10

07.09.2015, 22:38

4

В чём вопрос то?



0



6 / 6 / 5

Регистрация: 25.02.2015

Сообщений: 202

07.09.2015, 22:43

 [ТС]

5

Цитата
Сообщение от castaway
Посмотреть сообщение

В чём вопрос то?

как исправить эту аномалию, лишняя строчка кода не к чему…



0



Эксперт С++

4984 / 3091 / 456

Регистрация: 10.11.2010

Сообщений: 11,169

Записей в блоге: 10

07.09.2015, 22:57

6

Цитата
Сообщение от ДЕСАНТУРА
Посмотреть сообщение

как исправить эту аномалию

Никак.



0



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

int main()
{
int      // here's a comment, but it's ignored by the compiler
return 0;
}

Следующий код потерпит неудачу с ошибкой компиляции, более конкретно в VS2012 вы получите error C2143: syntax error : missing ';' before 'return', Это очевидная ошибка, поскольку у нас нет конечной точки с запятой для обозначения конца инструкции; добавьте точку с запятой, и она прекрасно скомпилируется, потому что мы не нарушали синтаксис языка C (или C ++ в данном случае):

int main()
{
int      // here's a comment, but it's ignored by the compiler
; // white space and comments are ignored by the compiler
return 0;
}

То же самое относится и к следующему коду:

int main()
{
__asm ; here's a comment but it's ignored

return 0;
}

Кроме здесь мы получаем ошибку error C2400: inline assembler syntax error in 'opcode'; found 'constant'потому что это лечит все после __asm Ключевое слово в качестве инструкции на ассемблере, и комментарий по праву игнорируется .. поэтому будет работать следующий код:

int main()
{
__asm ; here's a comment but it's ignored
NOP ; white space and comments are ignored by the compiler

__asm {; here's an __asm 'block'
} // outside of __asm block so only C style comments work
return 0;
}

Так что это отвечает на ваш первый вопрос: Why didn't VS allow me to add an assembly comment?.. потому что это является синтаксическая ошибка.

Теперь для вашего второго вопроса: Is there a different way to add an assembly comment without adding an instruction, including NOP?

Прямо нет, нет, но косвенно да есть. Стоит отметить, что __asm Ключевое слово компилируется во встроенную сборку в вашей программе, поэтому комментарии будут удаляться из скомпилированной сборки так же, как если бы это был стандартный комментарий C / C ++, поэтому пытаться «принудительно» вызвать комментарий в вашей сборке с помощью этого метода, вместо этого , вы можете использовать /FAs флаг компилятора, и он сгенерирует сборку (машинный код), смешанную с исходным кодом, например:

Учитывая следующий (очень простой) код:

int main()
{
// here's a normal comment
__asm { ; here's an asm comment and empty block
} // here's another normal comment
return 0;
}

Когда скомпилировано с /FAs флаг компилятора file.asm было получено следующее:

; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.31101.0

TITLE   C:\test\file.cpp
.686P
.XMM
include listing.inc
.model  flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC  _main
; Function compile flags: /Odtp
; File c:\test\file.cpp
_TEXT   SEGMENT
_main   PROC

; 2    :     {

push    ebp
mov ebp, esp

; 3    :         // here's a normal comment
; 4    :         __asm { ; here's an asm comment and empty block
; 5    :         } // here's another normal comment
; 6    :         return 0;

xor eax, eax

; 7    :     }

pop ebp
ret 0
_main   ENDP
_TEXT   ENDS
END

Обратите внимание, как он включает в себя источник и комментарии. Если бы этот код сделал больше, вы бы увидели больше ассемблера и связанный с ним источник.

Если вы хотите поместить комментарии в саму встроенную сборку, то вы можете использовать обычные комментарии в стиле C / C ++, а также комментарии сборки внутри __asm сам блок:

int main()
{
// here's a C comment
__asm { ; here's an asm comment
// some other comments
NOP ; asm type comment
NOP // C style comment
} // here's another comment
return 0;
}

Надеюсь, что это может помочь.

РЕДАКТИРОВАТЬ:

Следует отметить, что следующий фрагмент кода также компилируется без ошибок, и я не уверен на 100%, почему:

int main()
{
__asm
__asm ; comment
// also just doing it on a single line works too: __asm __asm
return 0;
}

Компиляция этого кода с единственным __asm ; comment выдает ошибку компиляции, но с обоими компилирует нормально; добавление инструкций к приведенному выше коду и проверка .asm выход показывает, что второй __asm игнорируется для любых других команд сборки, предшествующих ему. Так что я не уверен на 100%, если это ошибка синтаксического анализа или часть __asm Синтаксис ключевого слова, так как нет документации по этому поведению.

2

Ошибка – CAN’T CREATE OUTPUT FILE DISK MAY BE
FULL
(Невозможно
создание выходного (результирующего)
файла – возможно, диск полон).

Значение: либо возможно, что диск
действительно полон, либо операционная
система не позволяет, чтобы одновременно
было бы открыто необходимое число
файлов.

Ошибка – CAN’T OPEN INPUT FILE (Невозможно
открытие входного файла).

Значение: операционная система не
допускает одновременное открытие
необходимого числа файлов.

Ошибка – CAN’T FIND FILENAME.OBJ (Файл с именем
<имя-файла>.OBJ не обнаружен).

Значение: имя
объектного файла (файла с расширением
имени .OBJ) не существует, либо
операционная система не допускает
одновременного открытия необходимого
числа файлов.

Ошибка – SYNTAX ERROR (Синтаксическая
ошибка).

Значение: обычно эта ошибка возникает
из-за пропущенной запятой или круглой
скобки.

Ошибка – ILLEGAL ADDRESSING MODE (Неверный
режим адресации).

Значение: адресация операнда с
использованием данной формы адресации
недопустима.

Ошибка – MULTIPLY
DEFINED SYMBOL
(Символ
уже описан).

Значение: данный символ уже описан
ранее.

Ошибка – UNDEFINED SYMBOL (Символ не
определен).

Значение: символ не был описан в период
выполнения первого прохода ассемблера.

Ошибка – RELATIVE JUMP TOO LARGE (Слишком
далекий относительный переход).

Значение: результирующий адрес перехода
находится на другой странице.

Ошибка – ILLEGAL REGISTER (Недопустимое
использование регистра).

Значение: для данной команды недопустимо
использование указанного регистра.

Ошибка – ILLEGAL LABEL 1ST CHARACTER (Неверен
первый символ метки).

Значение: метка должна начинаться с
алфавитного символа.

Ошибка – MISSING LABEL (Пропущена метка).

Значение: в данной команде требуется
присутствие метки.

4 Общие сведения об интегрированной среде

ASM
EDITOR

Для запуска программы необходимо
запустить файл ASM_Ed.exe (ярлык программы
обычно находится на рабочем столе).

Рисунок 3 –
Внешний вид основного окна программы

Можно выделить следующие области
основного окна программы (рисунок 3):

Главное меню 1.

Кнопки быстрого доступа к функциям
главного меню 2.

Область написания программ 3.

Наиболее важные функции программы ASM
Editor представлены в таблице
1.

Таблица 1 – Основные функции программы
ASM Editor

Пункт меню

Выполняемая
функция

Комбинация
клавиш

1

2

3

Меню File

New

Создать
новый файл

Ctrl+N

Open

Открыть
файл

Ctrl+O

Save

Сохранить
файл

Ctrl+S

Save
as …

Сохранить
файл как …

Print

Печать

Продолжение таблицы 1

1

2

3

Exit

Выход из
программы

Ctrl+F10

Меню Edit

Undo

Отменить

Ctrl+Z

Redo

Вернуть

Ctrl+Y

Cut

Вырезать

Ctrl+X

Copy

Копировать

Ctrl+C

Paste

Вставить

Ctrl+V

Select All

Выделить
все

Ctrl+A

Move Right

Сдвинуть
вправо

Ctrl+R

Move Left

Сдвинуть
влево

Ctrl+L

Find

Найти

Ctrl+F

Replace

Заменить

Ctrl+R

Меню
Project

Compile

Resource

Скомпилировать
файл

F9

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Понравилась статья? Поделить с друзьями:
  • Синтаксическая ошибка 1с отчет
  • Синонимическая ошибка это
  • Синтаксическая норма это ошибка
  • Синоним человеческой ошибки
  • Синтаксическая ошибка 1с запрос