У меня есть код сортировки слиянием сборки, который я получил из Github, и я пытаюсь встроить его во встроенную сборку на C ++, но он не компилируется и продолжает возвращать эти ошибки:
1>c:usersmayankdesktopassemblyassemblymain.cpp(147): error C2415: improper operand type
Код, который я пытаюсь запустить, таков:
#include #include #include using namespace std; const int ARRAYSIZE = 30; int main() < int arr[ARRAYSIZE]; int temp_arr[ARRAYSIZE]; int number; for(int x = 0; x < ARRAYSIZE; x++) < number = (rand() % 99) + 1; arr[x] = number; >/* READ_ARR_LEN: __asm < // Read the length of the array //GetLInt [30] // Size of input array //PutLInt [30] >GET_ARRAY: __asm < //intel_syntax // Get values in arr from the user mov EAX, arr mov ECX, ARR_LEN call Read_Arr // Run Merge Sort on the array mov EAX, arr mov EBX, temp_arr mov ECX, ARR_LEN call Merge_Sort // EXIT >;; */ Merge_Sort: __asm < // EAX — Array start // ECX — array length // Arrays of size 0 or 1 are already sorted cmp ARRAYSIZE, 2 jl Trivial_Merge_Sort // Merge_Sort (first half) // Length of the first half // ECX /= 2 push ARRAYSIZE shr ARRAYSIZE, 1 call Merge_Sort pop ARRAYSIZE // Merge_Sort (second half) push arr push EBX push ARRAYSIZE // Length of the second half // ECX = ECX — ECX/2 mov EDX, ARRAYSIZE shr EDX, 1 sub ARRAYSIZE, EDX imul EDX, 4 // Start index of the second half // EAX = EAX + (ECX/2) * 4 add arr, EDX push EDX call Merge_Sort pop EDX pop ARRAYSIZE pop EBX pop arr pushad // Merge (first half, second half) // Length of first half = ECX/2 // Length of second half = ECX — ECX/2 mov EDX, ECX shr ECX, 1 sub EDX, ECX // Start of second half = EAX + (ECX/2) * 4 mov EBX, EAX mov EDI, ECX imul EDI, 4 add EBX, EDI // Index of temp array = 0 sub EDI, EDI call Merge popad // Copy back the merged array from temp_arr to arr call Merge_Copy_Back_Temp ret >; Trivial_Merge_Sort: __asm < // In case of arrays of length 0 or 1 ret >; Merge: __asm < // Merge two arrays contents. // The final merged array will be in temp_arr // Merging is done recursively. // Arguments: // EAX — First array’s start // EBX — Second array’s start // ECX — Length of first array // EDX — Length of second array // EDI — Index in temp array pushad // Handle the cases where one array is empty cmp ARRAYSIZE, 0 jz First_Array_Over cmp EDX, 0 jz Second_Array_Over // Compare first elements of both the arrays push ARRAYSIZE push EDI mov ARRAYSIZE, [arr] mov EDI, [ARRAYSIZE] cmp ARRAYSIZE, EDI pop EDI pop ARRAYSIZE // Pick which ever is the least and update that array jl Update_First_Array jmp Update_Second_Array >; Update_First_Array: __asm < // min_elem = min (first elements of first array and second array) // Put min_elem into the temp array push dword ptr [EAX] pop dword ptr [temp_arr + EDI * 4] add EAX, 4 dec ECX inc EDI // Recursively call Merge on the updated array and the // other array call Merge popad ret >; Update_Second_Array: __asm < // min_elem = min (first elements of first array and second array) // Put min_elem into the temp array push dword ptr [EBX] pop dword ptr [temp_arr + EDI * 4] add EBX, 4 dec EDX inc EDI // Recursively call Merge on the updated array and the // other array call Merge popad ret >; Merge_Copy_Back_Temp: __asm < // Copy back the temp array into original array // Arguments: // EAX — original array address // ECX — original array length pushad // For copying back, the destination array is EAX mov EBX, EAX // Now, the source array is temp_arr mov EAX, temp_arr call Copy_Array popad ret >; Trivial_Merge: __asm < // Note: One array is empty means no need to merge. popad ret >; First_Array_Over: __asm < // Copy the rest of the second array to the temp arr // because the first array is empty pushad mov EAX, EBX mov ECX, EDX mov EBX, temp_arr imul EDI, 4 add EBX, EDI call Copy_Array popad popad ret >; Second_Array_Over: __asm < // Copy the rest of the first array to the temp arr // because the second array is empty pushad mov EBX, temp_arr imul EDI, 4 add EBX, EDI call Copy_Array popad popad ret >; Copy_Array: __asm < // Copy array to destination array // EAX — Array start // EBX — Destination array // ECX — Array length // Trivial case cmp ECX, 0 jz Copy_Empty_Array push ECX sub EDI, EDI >; copy_loop: __asm < // Copy each element push dword ptr [EAX + EDI * 4] pop dword ptr [EBX + EDI * 4] inc EDI loop copy_loop pop ECX ret >; Copy_Empty_Array: __asm < ret >; Read_Arr: __asm < // EAX — array start // ECX — array length mov ESI, EAX sub EDI, EDI >; loop1: __asm < // Read each element lea eax,[esi+edx*4] inc EDI loop loop1 ret >; return 0; >
Создан 14 янв.
Mayankmmmx
спросил 12 Янв ’13 в 18:18
Mayankmmmx Mayankmmmx
115 1 1 золотой значок 2 2 серебряных значка 13 13 бронзовых знаков
ошибка частотника. рабочее видео для форума
ВИРУС на Ассемблере | Как программно отключить монитор?
Зачем вам нужно столько встроенной сборки? Разве вы не доверяете компилятору правильно оптимизировать код?
У вас есть фетиш на неподдерживаемый код?
Вы используете 64-битный компилятор? В таком случае вам придется найти другой способ решения этой проблемы. Вы уверены, что имеет смысл делать вручную собранную сортировку слиянием по сравнению с тем, что производит компилятор? И если это так, я думаю, вы получите немного больше производительности, если перестанете использовать pushad / popad.
Я использую inline только для тестирования и экспериментов. Я не собираюсь использовать эту фактическую программу. Это просто для личного обучения. Я тоже понимаю разницу. Я не понимал, что сказал беги.
Кроме того, что я должен использовать вместо pushad / popad?
( Обновление: в исходном коде, опубликованном в вопросе, были попытки адресовать память как DWORD [address] , что несовместимо с синтаксисом, используемым встроенным ассемблером Visual C ++, как я указываю в своем ответе ниже.)
Visual C ++ использует синтаксис MASM для своей встроенной сборки, поэтому вам нужно использовать DWORD PTR вместо просто DWORD . Вот что вызывает эти ошибки компиляции.
См., Например, эту таблицу из книги «Искусство сборки».
’13 в 16: 512013-02-03 16:51
Создан 12 янв.
Бег 53,9 км 9 9 золотых значков 72 72 серебряных знака 116 116 бронзовых знаков
Я очень ценю вашу помощь! Я снова скомпилировал код и получил только одну ошибку! Ошибка: 1> c: users mayank desktop assembly assembly main.cpp (289): error C2400: синтаксическая ошибка встроенного ассемблера в ‘opcode’; нашел ‘[‘
Наверное, GetLInt [ESI + EDI * 4] линия. Я не уверен, что GetLInt это должно быть (функция, которую вы объявили и определили где-то еще?). В этом случае это не то, как вы выполняете вызов функции в сборке x86. Вам нужно будет сделать что-то вроде lea eax,[esi+edx*4] / push eax / call GetLInt , и после этого должно быть возвращаемое значение, eax если функция следует стандартным соглашениям о вызовах.
Оказывается, я забыл этот код: READ_ARR_LEN: __asm Но теперь, когда я запускаю код, я получаю следующие ошибки: 1> c: users mayank desktop assembly assembly main.cpp (31): error C2400: синтаксическая ошибка встроенного ассемблера в ‘opcode’; found ‘[‘ (повторяется в строке 32) Поскольку я добавил больше кода, строки 31 и 32 имеют следующий вид: GetLInt [30] // Размер входного массива PutLInt [30] И, поскольку я внес вышеупомянутое редактирование, строка 297 выглядит следующим образом: lea eax, [esi + edx * 4] вызвать GetLInt
Я предложил, call потому что думал, что GetLInt это функция, которую вы пытались вызвать. Поскольку вы сейчас говорите, что это массив (из int или long ?), Вы не должны его вызывать. И GetLInt[30] не является действующей инструкцией по сборке x86. Вам, вероятно, следует обновить исходное сообщение своим полным текущим кодом, указать, в каких строках вы получаете ошибки компиляции и каковы были ваши намерения с этими ошибочными строками кода (т.е. что вы пытались сделать?).
Я обновил приведенный выше код, а также получил сообщения об ошибках. По сути, цель функций — вызвать массив, а затем прочитать каждый элемент.
В этом коде GetLInt фактически является макрос NASM, который включен во внешний файл определения макроса и вызывает функцию proc_GetLInt , которая, в свою очередь, предоставляется в объектном файле io.o , а исходного кода там нет. Проблема в том, что
- вы не понимали, GetLint что вам не хватает внешнего кода
- даже если вы взяли все файлы из этого репозитория, это будет работать, потому что макросы NASM не работают напрямую во встроенной сборке VC ++
- даже если вы исправили проблему с макросом, у вас по-прежнему нет GetLInt функции, потому что она предоставляется только как объектный файл linux, вам придется написать ее самостоятельно
Как это исправить?
Этот код должен был предоставить автономную программу на ассемблере, которая самостоятельно обрабатывает весь ввод / вывод. Поскольку вы встраиваете его в VC ++, в ваших руках уже есть гораздо более мощная обработка ввода-вывода. Используйте их вместо них, т.е. убедитесь, что значения, которые вы хотите отсортировать, уже присутствуют arr до запуска встроенной сборки.
Затем, глядя на код: Merge_Sort ожидает начало вашего массива в EAX , а его длину в ECX . Вы можете получить и то, и другое из своего кода на C ++. Когда вы сделаете это, вы больше не нужны READ_ARR_LEN и GET_ARRAY блоки из кода на ассемблере.
Я не очень хочу воспроизводить части кода с изменениями, так как я не могу найти файл лицензии на github, в котором говорилось бы, что я могу это сделать. Позвольте мне попытаться описать: вам нужно вручную переместить указатель arr на EAX и содержимое ARRAYSIZE внутрь EBX в самом начале процедуры ассемблера. (*) Как я вижу, вы уже позаботились о заполнении массива числами, так что делать там нечего.
Затем нужно удалить все ненужные функции ассемблера и их вызовы. Вы также должны либо объединить все свои отдельные __asm блоки в один, либо использовать внешние переменные для сохранения и восстановления регистров между блоками ( или прочитать руководство здесь , но использование только одного блока работает и менее хлопотно).
Наконец, вы должны быть осторожны с кадрами стека: каждый call должен иметь соответствие ret . Здесь легко споткнуться, поскольку процедура сортировки слиянием рекурсивна.
(*) Будьте осторожны со способом обработки переменных в блоках asm в VC ++, убедитесь, что действительно используете указатели, когда они вам нужны.
В общем, перенос этого на VC ++ — нетривиальная задача.
Источник: www.stackfinder.ru
Передача параметров Assembly/C++ в Visual Studio (синтаксическая ошибка встроенного ассемблера в «код операции»; обнаружен «неверный токен»)
Я пытаюсь написать программу с использованием Visual Studio, которая вызывает функцию C++, которая упаковывает некоторый оптимизированный код сборки. Я очень новичок в Ассамблее.
Я сгенерировал некоторую сборку и вижу это:
Я хочу заменить это
void myOptimizedAssemblyFunction (int arr[], int size) __asm < _i$66807 = -8 ; size = 4 _arr$ = 8 ; size = 4 _size$ = 12 ; size = 4
Но компилятор жалуется
error C2400: inline assembler syntax error in ‘opcode’; found ‘bad token’
Что я должен делать с этой ошибкой? Что означают эти строки сгенерированной сборки? Должен ли я просто установить несколько регистров на -8,8,12 и использовать их вместо этого?
Источник: stackru.com
Untitled
Ошибка 1 error C2400: синтаксическая ошибка во встроенном коде на языке ассемблера в «код операции»; обнаружено «newline» d:usersptencha-toshdocumentsvisual studio 2012projectspu_laba3pu_laba3laba3.c 22 1 pu_laba3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement
Lua | 2 min ago | 0.38 KB
GetText | 3 min ago | 0.24 KB
Arduino | 9 min ago | 0.48 KB
Arduino | 11 min ago | 1.22 KB
SQL | 11 min ago | 0.10 KB
Lua | 12 min ago | 2.94 KB
Arduino | 22 min ago | 0.83 KB
Lua | 22 min ago | 0.35 KB
Advertisement
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Источник: pastebin.com
Синтаксическая ошибка во встроенном коде на языке ассемблера
Доброго времени суток!
Редактирую исходник программки на MS Visual С++ с ассемблерными вставками. Программа изначально была написана вроде под Борланд С++, но его у меня нет. По этому переделываю под MS Visual C++. Все ошибки устранил, но одну побороть не могу. А именно:
db 0x66,0x59 // получаем так сказать ECX
int 0x1A // выполняем прерывание
mov b_h,bh // читаем
mov b_l,bl // данные
mov a_h,ah // в
mov s_i,si // переменные
>
Ругается на: db 0x66,0x59
Ошибка: error C2400: синтаксическая ошибка во встроенном коде на языке ассемблера в “код операции”; обнаружено “constant”
Программу писал не я. Надеюсь на вашу помощь. Спасибо!
- Готовые программы Assembler
- Использование арифметического сопроцессора
Формулировка задачи
14 голосов , оценка 3. 786 из 5
2016, 14:05. Показов 4863. Ответов 2
visual studio 2013 выдал такую ошибку error C2400: синтаксическая ошибка во встроенном коде на языке ассемблера в “код операции”; обнаружено “newline, что это за ошибка?
__________________Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
25 ответов
12 июня 2011 года
Как правильно записать в VC++ ? Чтобы не ругалось.
pop ecx
хотя не уверен.
С компилировалось, но под win 7 результат не запускается
А эта прога случайно не под дос была раньше?
Да, программка для доса. Пойду гуглить.
У доса ж прерывания другие. Естественно, что инструкции вида int. у вас работают некорректно.
Подскажите, что сделать то? Чтобы программа заработала
эта программа не для доса. в досе это прерывание устанавливаетчитает системное время.
INT 1A – PCI BIOS v2. 0c+ – FIND PCI CLASS CODE
AX = B103h
ECX = class code (see also #F0085,#00878)
bits 31-24 unused
bits 23-16 class
bits 15-8 subclass
bits 7-0 programming interface
SI = device index (0-n)
Return: CF clear if successful
CF set on error
AH = status (00h,86h) (see #00729)
00h successful
BH = bus number
BL = device/function number (bits 7-3 device, bits 2-0 func)
86h device not found
EAX, EBX, ECX, and EDX may be modified
all other flags (except IF) may be modified
Notes: this function may require up to 1024 byte of stack; it will not enable
interrupts if they were disabled before making the call
the meanings of BL and BH on return were exchanged between the initial
drafts of the specification and final implementation
all devices sharing the same Class Code may be enumerated by
incrementing SI from 0 until error 86h is returned
наверное, нужно будет делать драйвер.
Программка для сканирования подключенных устройств.
Всем спасибо, буду разбираться с Борландом
Мальчик/Девочка (RM/PM) – какая разница.
Вы лучше обозначте то, что вам надо.
Сканер PCI шины, есть исходник, рабочий, но он не компилируется. Код написан на Борланд С++, на VS C++ не компилируется, хотя я и исправил все, вроде как правильно. на экран должно вывести какие устройства подключены к ПК.
Это вам надо сделать под какую платформу Windows али DOS?
PS: А работать ваша программа будет только в ДОСе, причем откомпилированная для него же, VS C++ компилирует как бы для Windows.
Тогда чем откомпилировать код, для ДОСа? Подскажите плз.
13 июня 2011 года
зачем компилировать под дос, если запускаться будет в винде?
С компилировалось, запускается и вроде работает. Спасибо!
Единственно, не показывает устройства.
Вопрос все тот же, про мальчика с девочкой. Где вы ее запускаете в DOSе или в Windows’е?
Запускаю в Windows, программа запускается, выводит сообщение, PCI Bios disabled
mov _ah,ah // если в ah 0 то идем дальше, иначе вывод сообщения PCI Bios disabled
Запускал программу через DOSBox 0. 74, результат точно такой же.
PS: Возвращаемся к условию задачи?
Тогда подскажите плз, как мне ее в чистом ДОСе запустить?
Очевидно, что водрузив ДОС на физической машине, тогда вы получите список реальных PCI устройств. Либо водрузив ДОС в виртуальной машине в этом случае вы получите список виртуальный устройств.
PS: В итоге, я бы Вам всеже рекомендовал огласить условия задачи и контекст в котором данная задача выполняется.
Запустил из под ДОСа, работает! Спасибо за советы!
Источник: codoshibki.ru