I'm working on small project and trying to get some hardcoded values to inline assembly. For doing that I'm using templates. I have created a code snip to show what I'm seeing
#include <iostream>
template <size_t T>
struct MyClass
{
size_t myValue = T;
void doSomething()
{
size_t value = T;
__asm
{
mov eax, [T]
mov [value], eax
}
std::cout << value << std::endl;
}
};
int main()
{
auto o = new MyClass<999>();
o->doSomething();
return 0;
}
It turns out that for the assembly code it is trying to use the data segment instead "pasting the number there directly"
; 25 : {
push ebp
mov ebp, esp
push ecx
; 26 : auto o = new MyClass<999>();
push 4
call ??2@YAPAXI@Z ; operator new
add esp, 4
; 14 : size_t value = T;
mov DWORD PTR _value$2[ebp], 999 ; 000003e7H
; 26 : auto o = new MyClass<999>();
mov DWORD PTR [eax], 0
mov DWORD PTR [eax], 999 ; 000003e7H
; 15 : __asm
; 16 : {
; 17 : mov eax, [T]
mov eax, DWORD PTR ds:0
; 18 : mov [value], eax
mov DWORD PTR _value$2[ebp], eax
; 19 : }
; 20 : std::cout << value << std::endl;
I'm using Visual Studio 2015. Is there any other way to achieve this.
Thanks in advance
Tritron.
Template class. is an instance of a class template. A template definition is identical to any valid class definition that the template might generate, except for the following: The class template definition is preceded by template< template-parameter-list >
Simply put, you may use templates to construct a single function or single class that works with several data types.
Templates are very useful when implementing generic constructs like vectors, stacks, lists, queues which can be used with any arbitrary type. C++ templates provide a way to re-use source code as opposed to inheritance and composition which provide a way to re-use object code.
Template class works as a container that comes in very handy when multiple classes will be performing the same function in a similar way for different data types. This container will wrap the functionality in a single entity that can be utilized for different data types as per the requirement.
Ahh, what a lovely and twisted question!
I tried a constexpr variable initialized with T. The result was the same - value loaded from memory. Macros can be used to pass literals to inline assembly, but they don't mix well with templates.
Initializing an enum inside the class using T should in theory work (https://msdn.microsoft.com/en-us/library/ydwz5zc6.aspx mentions enums can be used in inline assembly), but using that in the inline assembly crashes the visual studio 2015 compiler :-).
What seems to work is a function template that declares an enum using the template parameter, and then using that enum in the inline assembly. If you must have it in a templated class, you can instantiate the template function inside the class like this:
#include <iostream>
template <size_t T> void dosomething() {
enum { LOCALENUM = T };
size_t value = 0;
__asm
{
mov eax, LOCALENUM
mov[value], eax
}
std::cout << value << std::endl;
}
template <size_t T>
struct MyClass
{
size_t myValue = T;
void doSomething()
{
::dosomething<T>();
}
};
int main()
{
//dosomething<999>();
auto o = new MyClass<999>();
o->doSomething();
return 0;
}
This results in the following assembly code:
auto o = new MyClass<999>();
001B1015 mov dword ptr [eax],0
001B101B mov dword ptr [eax],3E7h
o->doSomething();
001B1021 mov eax,3E7h <--- Victory!
001B1026 mov dword ptr [ebp-4],eax
001B1029 mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (01B2048h)]
001B102F push offset std::endl<char,std::char_traits<char> > (01B1050h)
001B1034 push dword ptr [ebp-4]
001B1037 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (01B2044h)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With