I am using the following code:
int _tmain(int argc, _TCHAR* argv[])
{
__asm{
"MOV EAX, DMSN[0]";
"LEA EBX, DMSN[0]";
"CALL EBX";
};
return 0;
}
MOV EAX and LEA EBX, will later contain two different arrays.
But as for the example they will contain the same.
I am using the following:
const BYTE DMSN[694]={blah, blah, blah};
But i am turning up with these erros:
1>c:\users\1337\documents\visual studio 2010\projects\test2\test2\test2.cpp(49): error C2400: inline assembler syntax error in 'opcode'; found 'bad token'
1>c:\users\1337\documents\visual studio 2010\projects\test2\test2\test2.cpp(50): error C2400: inline assembler syntax error in 'opcode'; found 'bad token'
1>c:\users\1337\documents\visual studio 2010\projects\test2\test2\test2.cpp(51): error C2400: inline assembler syntax error in 'opcode'; found 'bad token'**strong text**
What is wrong?
Your syntax is faulty, use it like this:-
int _tmain(int argc, _TCHAR* argv[])
{
_asm{
mov eax, DMSN[0]
lea ebx, DMSN[0]
call ebx
}
return 0;
}
for VS based compiler.
if dmsn is array, you dont have to put [0] to access first element
int _tmain(int argc, _TCHAR* argv[])
{
__asm{
mov eax, DMSN
lea ebx, DMSN
call ebx
};
return 0;
}
mov instruction will automatically check for the operand sizes and will take first 32 bits into register(eax) and 32 bit effective address to register(ebx)
VC++ 2010 express
Related
#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
const char* message = ("hi");
__asm {
print:
push ebp;
mov ebp, esp;
mov ebx, [ebp + 8]; <- First argument
push ebx;
call printf;
mov esp, ebp;
pop ebp;
ret;
mov eax, message;
push eax;
call print;
};
std::cin.get();
return (0);
};
I'm using an inline assembler obviously.
I don't understand why this is an error, I've tried using leave instead of destroying the stack frame manually, no luck. I don't understand where I went wrong here.
I am trying to use inline assembler __asm in my C program with Intel syntax as opposed to AT&T syntax. I am compiling with gcc -S -masm=intel test.c
but it is giving error. Below is my test.c file.
#include <stdio.h>
//using namespace std;
int AsmCode(int num,int power) {
__asm {
mov eax, num;
mov ecx, power;
shl eax, cl;
};
}
int main()
{
printf("eax value is %d\n",AsmCode(2,3));
//getchar();
return 0;
}
Expected result was eax value is 16, but errors are occurring like unknown type name 'mov',unknown type name 'shl' etc.
Edit:
I have updated the code as:
int AsmCode(int num,int power) {
__asm__ (
"movl eax, num;"
"mov ecx, power;"
"shl eax, cl;"
);
}
int main()
{
printf("eax value is %d\n",AsmCode(2,3));
return 0;
}
And compiled this code with gcc -S -masm=intel test.c. This resulted in NO OUTPUT, whereas it should produce output as eax value is 16.
When compiled with gcc test.c it produced the errors:
Error: too many memory references for 'mov'
Error: too many memory references for 'shl'
Please help..
The most important error is the first one:
main.cpp:4:11: error: expected '(' before '{' token
__asm {
^
(
You're using the wrong syntax for GCC. You've used Microsoft Visual Studio syntax. So, your GCC doesn't know that you're trying to give it assembly instructions.
Instead of __asm { ... }, it should be __asm__ ( "..." ).
Like this:
int AsmCode(int num,int power) {
__asm__ (
"mov eax, num;"
"mov ecx, power;"
"shl eax, cl;"
);
}
Read more here.
Note that there are further issues with your ASM that you should ask about separately.
I got the snippet below from this comment by #CaffeineAddict.
#include <iostream>
template<typename base_t, typename expo_t>
constexpr base_t POW(base_t base, expo_t expo)
{
return (expo != 0) ? base * POW(base, expo - 1) : 1;
}
int main(int argc, char** argv)
{
std::cout << POW((unsigned __int64)2, 63) << std::endl;
return 0;
}
with the following disassembly obtained from VS2015:
int main(int argc, char** argv)
{
009418A0 push ebp
009418A1 mov ebp,esp
009418A3 sub esp,0C0h
009418A9 push ebx
009418AA push esi
009418AB push edi
009418AC lea edi,[ebp-0C0h]
009418B2 mov ecx,30h
009418B7 mov eax,0CCCCCCCCh
009418BC rep stos dword ptr es:[edi]
std::cout << POW((unsigned __int64)2, 63) << std::endl;
009418BE mov esi,esp
009418C0 push offset std::endl<char,std::char_traits<char> > (0941064h)
009418C5 push 3Fh
009418C7 push 0
009418C9 push 2
009418CB call POW<unsigned __int64,int> (09410FAh) <<========
009418D0 add esp,0Ch
009418D3 mov edi,esp
009418D5 push edx
009418D6 push eax
009418D7 mov ecx,dword ptr [_imp_?cout#std##3V?$basic_ostream#DU?$char_traits#D#std###1#A (094A098h)]
009418DD call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (094A0ACh)]
009418E3 cmp edi,esp
009418E5 call __RTC_CheckEsp (0941127h)
009418EA mov ecx,eax
009418EC call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (094A0B0h)]
009418F2 cmp esi,esp
009418F4 call __RTC_CheckEsp (0941127h)
return 0;
009418F9 xor eax,eax
}
which shows (see the characters "<<======" introduced by me in the disassembly) that the compiler didn't evaluate the function POW at compile time. From his comment, #CaffeineAddict seemed to expect this behavior from the compiler. But I still can't understand why was this expected at all?
Two reasons.
First, a constexpr function isn't guaranteed to be called at compile time. To force the compiler to call it at compile time, you must store it in a constexpr variable first, i.e.
constexpr auto pow = POW((unsigned __int64)2, 63);
std::cout << pow << std::endl;
Secondly, you must build the project in Release configuration. In VS, you'll find you can break-point through constexpr functions if you have built the project using Debug configuration.
I have the following C++ code
int myFuncSum( int a, int b)
{
int c;
c = a + b;
return c;
}
int main(int argc, char *argv[])
{
int result;
result = myFuncSum(100, 200);
return 0;
}
When I step through this in the disassembly window of Visual Studio 2008 on my Win7 Pro machine, I see the following for the call to myFuncSum():
int myFuncSum( int a, int b)
{
001C1000 push ebp
001C1001 mov ebp,esp
001C1003 push ecx
int c;
c = a + b;
001C1004 mov eax,dword ptr [a] <--------------------
001C1007 add eax,dword ptr [b] <--------------------
001C100A mov dword ptr [c],eax <--------------------
return c;
001C100D mov eax,dword ptr [c] <--------------------
}
As I have indicated, the four lines that refer to the variables a, b and c refer to them as such, not as offsets relative to EBP.
Can anyone please suggest what I need to do to Visual Studio to get it to refer to them via EBP? I have already disabled C++ optimisations in the project settings; without doing so I don't even get my function called.
The disassembler is just trying to be helpful, not spamming you too much about irrelevant details. Not entirely accidental, this syntax abbreviation is also permitted in inline assembly with the __asm keyword.
You can switch back-and-forth, right-click the disassembly window and untick Show Symbol Names. Now you'll see the real machine code:
c = a + b;
003613DE mov eax,dword ptr [ebp+8]
003613E1 add eax,dword ptr [ebp+0Ch]
003613E4 mov dword ptr [ebp-8],eax
return c;
003613E7 mov eax,dword ptr [ebp-8]
I bumped into a very serious error using visual studio 2005, running a C++ Win32 Console application. The problem will show when running the code below (simplified), using the following project properties: C++|optimization|optimization|/O2 (or /O1, or /Ox), C++|optimization|Whole program optimization|/GL, linker|optimization|/ltcg
#include "stdafx.h"
#include <iostream>
using namespace std;
const int MAXVAL=10;
class MyClass
{
private:
int p;
bool isGood;
public:
int SetUp(int val);
};
int MyClass::SetUp(int val)
{
isGood = true;
if (MAXVAL<val)
{
int wait;
cerr<<"ERROR, "<<MAXVAL<<"<"<<val<<endl;
cin>>wait;
//exit(1); //for x64 uncomment, for win32 leave commented
}
if (isGood) p=4;
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
int wait=0, setupVal1=10, setupVal2=12;
MyClass classInstance1;
MyClass classInstance2;
if (MAXVAL>=setupVal1) classInstance1.SetUp(setupVal1);
if (MAXVAL>setupVal2) classInstance2.SetUp(setupVal2);
cerr<<"exit, enter value to terminate\n";
cin>>wait;
return 0;
}
The output shows that value 10 is smaller then value 10! I already found out that changing setting /O2 to /Od solves the problem (setting /Og, which is part of /O2, causes the problem), but that really slows down the execution time. Also changing the code a bit can solve it but hey, I can never be sure that the code is reliable. I am using Visual studio 2005 professional (Version 8.0.50727.867), os windows 7.
My questions are: can someone try to reproduce this error using Visual Studio 2005, (I already tried VS 2010, no problem), and if so, what happens here?
Can I assume that newer versions have solved this problem (I consider buying VS 2012)
Thank you
You can reduce your example significantly and still get the same problem! You don't need two instances, and you don't need any of the other local or member variables. Also, you can hardcode MAXVAL.
Quick summary of what "solves" the problem:
making MAXVAL a nonconst int
setting setupVal2 to a value less than 10
surprisingly, changing the condition 10<val to val>10 !!!
Here's my minimal version to reproduce the problem:
#include "stdafx.h"
#include <iostream>
using namespace std;
class MyClass
{
public:
int SetUp(int val);
};
int MyClass::SetUp(int val)
{
if (10<val)
cout<<10<<"<"<<val<<endl;
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
int setupVal1=10, setupVal2=12;
MyClass classInstance;
classInstance.SetUp(setupVal1);
classInstance.SetUp(setupVal2);
cin.get();
return 0;
}
The problem, as witnessed by the disassembly, is that the compiler thinks 10<val is always true and therefore omits the check.
_TEXT SEGMENT
?SetUp#MyClass##QAEHH#Z PROC ; MyClass::SetUp
; _val$ = ecx
; 16 : if (10<val)
; 17 : cout<<10<<"<"<<val<<endl;
mov eax, DWORD PTR __imp_?endl#std##YAAAV?$basic_ostream#DU?$char_traits#D#std###1#AAV21##Z
push eax
push ecx
mov ecx, DWORD PTR __imp_?cout#std##3V?$basic_ostream#DU?$char_traits#D#std###1#A
push 10 ; 0000000aH
call DWORD PTR __imp_??6?$basic_ostream#DU?$char_traits#D#std###std##QAEAAV01#H#Z
push eax
call ??$?6U?$char_traits#D#std###std##YAAAV?$basic_ostream#DU?$char_traits#D#std###0#AAV10#PBD#Z ; std::operator<<<std::char_traits<char> >
add esp, 4
mov ecx, eax
call DWORD PTR __imp_??6?$basic_ostream#DU?$char_traits#D#std###std##QAEAAV01#H#Z
mov ecx, eax
call DWORD PTR __imp_??6?$basic_ostream#DU?$char_traits#D#std###std##QAEAAV01#P6AAAV01#AAV01##Z#Z
; 18 : return 1;
mov eax, 1
; 19 : }