Here is the (almost 1:1) working code you posted for a standalone assembly.
binsearch.cpp
extern "C"
{
bool BinSearch(int searchNum, int myArray[], int arraySize);
};
// This is the inlined version.
bool BinSearchInline(int searchNum, int myArray[], int arraySize)
{
int middle;
int first;
int last;
char found;
_asm
{
push ebx
push esi
push edi
mov first,0
mov eax, arraySize
sub eax,1
mov last ,eax
mov found,0
LocalLoop:
mov eax, first
cmp eax, last
jg NotFound
mov eax, first
add eax, last
cdq
sub eax,edx
sar eax,1
mov middle,eax
mov eax,middle
mov ecx,myArray
mov edx,searchNum
cmp edx, dword ptr [ecx+eax*4]
jle MaybeLower
mov eax, middle
add eax,1
mov first, eax
jmp WhileLoop
MaybeLower:
mov eax, middle
mov ecx, myArray
mov edx, searchNum
cmp edx,dword ptr [ecx+eax*4]
jge Found
mov eax, middle
sub eax,1
mov last, eax
jmp WhileLoop
Found:
mov al,1
jmp Done
WhileLoop:
jmp LocalLoop
NotFound:
xor al,al
Done:
pop edi
pop esi
pop ebx
};
}
int main(int argc, char*arg[])
{
int testvalues[7];
for(int i = 0; i < 7; i++)
testvalues[i] = i;
bool b = BinSearch(8, testvalues, 7); // false, value not in array
b = BinSearch(3, testvalues, 7); // true, value is in array.
b = BinSearchInline(8, testvalues, 7); // false
b = BinSearchInline(3, testvalues, 7); // true
return 0;
}
binsearch.asm
.486
.model flat, C
option casemap :none
.code
BinSearch PROC, searchNum:DWORD, myArray:PTR DWORD, arraySize:DWORD
LOCAL first:DWORD
LOCAL middle:DWORD
LOCAL last:DWORD
LOCAL found:BYTE
push ebx
push esi
push edi
; This block is only for debugging stack errors and should be removed.
; lea edi,[ebp-0F0h]
; mov ecx,3Ch
; mov eax,0CCCCCCCCh
; rep stos dword ptr es:[edi]
mov dword ptr [first],0
mov eax,dword ptr [arraySize]
sub eax,1
mov dword ptr [last],eax
mov byte ptr [found],0 ; not even used.
@@Loop:
mov eax,dword ptr [first]
cmp eax,dword ptr [last]
jg @@NotFound
mov eax,dword ptr [first]
add eax,dword ptr [last]
cdq
sub eax,edx
sar eax,1
mov dword ptr [middle],eax
mov eax,dword ptr [middle]
mov ecx,dword ptr [myArray]
mov edx,dword ptr [searchNum]
cmp edx,dword ptr [ecx+eax*4]
jle @@MaybeLower
mov eax,dword ptr [middle]
add eax,1
mov dword ptr [first],eax
jmp @@WhileLoop
@@MaybeLower:
mov eax,dword ptr [middle]
mov ecx,dword ptr [myArray]
mov edx,dword ptr [searchNum]
cmp edx,dword ptr [ecx+eax*4]
jge @@Found
mov eax,dword ptr [middle]
sub eax,1
mov dword ptr [last],eax
jmp @@WhileLoop
@@Found:
mov al,1
jmp @@Done
@@WhileLoop:
jmp @@Loop
@@NotFound:
xor al,al
@@Done:
pop edi
pop esi
pop ebx
ret
BinSearch ENDP
END
Причина, по которой это не работает, заключается в том, что __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
|
0 / 0 / 0 Регистрация: 10.06.2015 Сообщений: 136 |
|
|
1 |
|
|
18.08.2016, 12:33. Показов 4328. Ответов 4
visual studio выдал такую ошибку
0 |
|
1550 / 875 / 179 Регистрация: 05.12.2015 Сообщений: 2,555 |
|
|
18.08.2016, 12:45 |
2 |
|
Anette666k, Код в студию.
0 |
|
Anette666k 0 / 0 / 0 Регистрация: 10.06.2015 Сообщений: 136 |
||||
|
18.08.2016, 14:46 [ТС] |
3 |
|||
0 |
|
obivan Падаван С++ 447 / 261 / 89 Регистрация: 11.11.2014 Сообщений: 916 |
||||||||
|
18.08.2016, 14:58 |
4 |
|||||||
|
РешениеAnette666k, ну судя по коментариям то вопервых код не так как надо будет работать потому что результат всегда будет 9
потому что в коде сверху всегда 0 Добавлено через 2 минуты
вот вам код если хотите чтобы было решение на 3*x + 9
0 |
|
Заблокирован |
|
|
18.08.2016, 15:32 |
5 |
|
и кто тут SHL?
0 |
Я тестировал код С и наткнулся на эту странную
ошибка компилятора
Следующий код не будет компилировать
#include<stdio.h>
void main()
{
int length=6;
__asm
{
mov eax,length
}
}
Visual Studio сообщает о следующей ошибке
test.c(7) : error C2400: inline assembler syntax error in 'second operand';
found 'newline'
Однако я заметил, что если я изменил имя переменной на что-то еще, скажу lengths, тогда все было в порядке, следующий код компилируется без труда
#include<stdio.h>
void main()
{
int lengths=6;
__asm
{
mov eax,lengths
}
}
Я пробовал с другими компиляторами, такими как Digital Mars и Intel Compiler, но везде первый код не может быть скомпилирован.
В чем может быть проблема? Есть ли другое определение для length в другом месте.
Я также хотел бы добавить, что это один файл, а не проект, поэтому
не может быть никаких множественных объявлений.
Я тестировал код C и наткнулся на эту странную ошибку компилятора
Следующий код не компилируется
#include<stdio.h>
void main()
{
int length=6;
__asm
{
mov eax,length
}
}
Visual Studio сообщает о следующей ошибке
test.c(7) : error C2400: inline assembler syntax error in 'second operand';
found 'newline'
Однако я заметил, что если я изменил имя переменной на что-то еще, например lengths, тогда все было в порядке, следующий код компилируется без каких-либо проблем
#include<stdio.h>
void main()
{
int lengths=6;
__asm
{
mov eax,lengths
}
}
Я пробовал с другими компиляторами, такими как Digital Mars и Intel Compiler, но везде первый код не может быть скомпилирован.
В чем может быть проблема? Есть ли другое определение для length где-нибудь еще?
Я также хотел бы добавить, что это один файл, а не проект, поэтому не может быть нескольких объявлений.
2 ответа
Лучший ответ
См. Здесь: http://msdn.microsoft. com / en-US / library / wxh0awwe% 28v = vs.80% 29.aspx
В частности
Операторы LENGTH, SIZE и TYPE имеют ограниченное значение во встроенной сборке. Их вообще нельзя использовать с оператором DUP (потому что вы не можете определять данные с помощью директив или операторов MASM). Но вы можете использовать их для определения размера переменных или типов C или C ++:
7
Scotty Bauer
18 Ноя 2013 в 21:42
Я думаю, причина может быть в том, что length является функцией-членом
Также MSDN говорит:
Операторы LENGTH , SIZE и TYPE имеют ограниченное значение во встроенных сборка. Их вообще нельзя использовать с оператором DUP (т.к. вы не можете определять данные с помощью директив или операторов MASM). Но ты можешь используйте их, чтобы узнать размер переменных или типов C или C ++:
Оператор LENGTH может возвращать количество элементов в массиве. Это возвращает значение 1 для переменных, не являющихся массивом.
8
Rahul Tripathi
18 Ноя 2013 в 21:40

Сообщение было отмечено Anette666k как решение