Visual C++ не поддерживает 64-битный встроенный ассемблер.
В результате вы получите ошибку при попытке компиляции следующего кода:
void waitvrt(void)
{
__asm {
mov dx,3dah
VRT:
in al,dx
test al,8
jnz VRT
NoVRT:
in al,dx
test al,8
jz NoVRT
}
}
1>.Third_partySrcCreditsThread.cpp(111) :
error C4235: nonstandard extension used :
'__asm' keyword not supported on this architecture
Если вам все же необходимо использовать ассемблерный код, то можно воспользоваться внешним 64-битным ассемблером, например, MASM.
Но скорее всего вам следует переписать данный код на языке Си/Си++. Высока вероятность, что ассемблерный код уже устарел и рационально использовать современные функции операционной системы или конструкции языка Си/Си++. Использование ассемблера для оптимизации в настоящее время редко оправдано, так как компилятор Visual C++ в большинстве случаев создаст достаточно эффективный код. Также не забывайте про возможность использования intrinsic-функций.
Intrinsic-функции — это специальные системно-зависимые функции, выполняющие действия, которые невозможно выполнить на уровне Си/Си++ кода или которые выполняют эти действия намного эффективнее. По сути, они позволяют избавиться от использования inline-ассемблера, так как его использование часто нежелательно или невозможно.
Программы могут использовать intrinsic-функции для создания более быстрого кода за счет отсутствия накладных расходов на вызов обычного вида функций. При этом, естественно, размер кода будет чуть-чуть больше. В MSDN приводится список функций, которые могут быть заменены их intrinsic-версией. Это, например, memcpy, strcmp и другие.
В компиляторе Microsoft Visual C++ есть специальная опция «/Oi», которая позволяет автоматически заменять вызовы некоторых функций на intrinsic-аналоги.
Помимо автоматической замены обычных функций на intrinsic-варианты, можно явно использовать в коде intrinsic-функции. Вот для чего это может быть нужно:
- Как уже говорилось, встроенный (inline) ассемблерный код не поддерживается компилятором Visual C++ в 64-битном режиме. Intrinsic-код поддерживается.
- Intrinsic-функции проще использовать, так как они не требуют знания регистров и других подобных низкоуровневых конструкций.
- Intrinsic-функции обновляются в компиляторах. Ассемблерный же код придется обновлять вручную.
- Встроенный оптимизатор не работает с ассемблерным кодом, поэтому требуется внешняя линковка модуля. Для intrinsic-кода такого не нужно.
- Intrinsic-код легче переносить, чем ассемблерный.
Использование intrinsic-функций в автоматическом режиме (с помощью ключа компилятора) позволяет получить бесплатно несколько процентов прироста производительности, а «ручное» — даже больше. Поэтому использование intrinsic-функций вполне оправдано.
Более подробно с применением intrinsic-функций можно ознакомиться в блоге команды Visual C++.
Присылаем лучшие статьи раз в месяц
- Remove From My Forums
-
Question
-
Dear All,
I am proting a project from VS2003 and OS running was Windows 2003 Server 32 bit to Vs2010 in Window 2008 Server 64bit.I have set of code snippets in my code.
__asm
{
mov eax, dword ptr [ebp + 0x4]
mov dword ptr [memoryAllocator], eax
}When I try to compile it in Vs2010 I get the following error.
nonstandard extension used : ‘__asm’ keyword not supported on this architecture
What would be the workaround for this and equivalent code in VS2010?
Many thanks in advance.
-R
Answers
-
Also consider this:
#include <intrin.h>
void * memoryAllocator = _ReturnAddress();
-
Proposed as answer by
Friday, March 26, 2010 2:50 PM
-
Marked as answer by
rajukgp
Saturday, March 27, 2010 3:35 AM
-
Proposed as answer by
Why do I get a compiler error C4235 complaining about the _asm keyword when building a Simulink Real-Time model in MATLAB R2014a?
I am trying to build a Simulink model for a Simulink Real-Time target in MATLAB R2014a but the build fails with the following error.
«error C4235: nonstandard extension used : ‘_asm’ keyword not supported on this architecture»
I have «mex -setup» set to Visual Studio 2013 and have not had any issues with building non-Simulink Real-Time models before. What is going on?
Accepted Answer
Microsoft Visual C++ Professional does not support all features of Stateflow and Simulink Real-Time. Refer to the following link for a list of supported compilers for MATLAB R2014a and check the column labeled «Simulink Real-Time».
More Answers (0)
See Also
Categories
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
I am building 64-bit nss 3.39 on Windows 10 with Microsoft Visual Studio 2017. It failed with the error:
error C4235: nonstandard extension used : '__asm' keyword not supported on this architecture
Has anyone faced this issue? Need solution on this.
Steps I followed:
- Installed Visual Studio 2017 (Enterprise trial edition) as mentioned in the Windows Prerequisites for Firefox build.
- Installed Rust.
- Installed MozillaBuild, downloaded from MozillaBuild Package.
- Downloaded the NSS package of release 3.39 (nss-3.39-with-nspr-4.20.tar.gz) from http://ftp.mozilla.org/pub/security/nss/releases/NSS_3_39_RTM/
- Created a directory C:src Extracted nss to c:/src (this looks like C:/src/nss-3.39)
- Run the C:Program Files (x86)Microsoft Visual Studio2017EnterpriseVCAuxiliaryBuildvcvars64.bat
- Run C:mozilla-buildstart-shell.bat
- Set
MOZ_NO_RESET_PATH=1
so this will not override the PATH variable. -
Created the required env variables,
export OS_TARGET=WIN95 export BUILD_OPT=1 export HOME="/c/src"
-
cd ~
(To bring me into my home directory). - Now
cd
into the nss-3.5nss Build usingmake nss_build_all
Now with these options: USE_64=1 BUILD_OPT=1 make nss_build_all
I am getting the following error:
gtest/include/gtest/internal/gtest-port.h(999): error C2220: warning treated as error - no 'object' file generated... [some build messages]...
make[2]: *** [WIN954.0_x86_64_64_OPT.OBJ/gtest/src/gtest-all.obj] Error 2
make[2]: Leaving directory /c/src/nss-3.39/nss/gtests/google_test'
make[1]: *** [libs] Error 2
make[1]: Leaving directory /c/src/nss-3.39/nss/gtests'
make: *** [libs] Error 2
phuclv
36k13 gold badges147 silver badges456 bronze badges
asked Oct 9, 2018 at 7:59
6
Installing CYGWIN and disabling ‘gtests’ worked for me. To disable GTests, set NSS_DISABLE_GTESTS=1
Here are some troubleshooting:
-
If you get following errors which are due to lack of some libraries and includes then remove two variables from C:mozilla-buildstart-shell.bat (basically, you should not initialize them with empty values so it can pick up required libraries from Windows)
SET INCLUDE= SET LIB=
Error Ex.:
c:srcnss-3.39nsscpputildatabuffer.h(10): fatal error C1083: Cannot open include file: 'algorithm': No such file or directory make[1]: *** [WINNT6.2_x86_64_64_OPT.OBJ/databuffer.obj] Error 2 make[1]: Leaving directory `/c/src/nss-3.39/nss/cpputil' make: *** [libs] Error 2
Re-execute steps from step 8 onwards.
-
If your build is failed due to assembly code/assembly keywords then install some assembly compiler(I have installed CYGWIN) and add into your path or set CYGWIN variable value in C:mozilla-buildstart-shell.bat.
Error Ex.:
error C4235: nonstandard extension used : '__asm' keyword not supported on this architecture
This happens because inline asm on 64-bit development is not a supported scenario by VS2017.
-
NSS 3.39 is using gtest 1.7 and it throws TR1 deprecation warnings. This could lead into build failure. If you see error like following then by disabling ‘gtests’, you can compile NSS successfully. To do this, before starting build set
NSS_DISABLE_GTESTS=1
Error Ex.:
gtest/include/gtest/internal/gtest-port.h(999): error C2220: warning treated as error - no 'object' file generated gtest/include/gtest/internal/gtest-port.h(999): warning C4996: 'std::tr1': warning STL4002: The non-Standard std::tr1 namespace and TR1-only machinery are deprecated and will be REMOVED. You can define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING to acknowledge that you have received this warning
Though this issue has been fixed into Mozilla build system project, it is not reflected in NSS. I think, NSS needs to be updated to use gtest 1.8.
Following are the steps I followed to build NSSv3.39 (with NSPR) successfully on Windows 10 (64-bit) with VS2017.
- Installed Visual Studio 2017 (Enterprise trial edition) as mentioned in the Windows Prerequisites for Firefox build.
- Installed Rust.
- Installed MozillaBuild, downloaded from MozillaBuild Package.
- Installed CYGWIN.
- Download the NSS package of release 3.39 (nss-3.39-with-nspr-4.20.tar.gz) from
- Created a directory
C:src
- Extracted nss to
c:/src
(this is looking like C:/src/nss-3.39) -
Run the
C:Program Files (x86)Microsoft Visual Studio2017EnterpriseVCAuxiliaryBuildvcvars64.bat
-
Run
C:mozilla-buildstart-shell.bat
- Set
MOZ_NO_RESET_PATH=1
so this will not override the PATH variable. -
Created the required env variables,
export OS_TARGET=WINNT export USE_64=1 export BUILD_OPT=1 export NSS_DISABLE_GTESTS=1 export HOME="/c/src"
-
cd ~
(To bring into home directory). - Now cd into the nss-3.5nss
- Build using
make nss_build_all
phuclv
36k13 gold badges147 silver badges456 bronze badges
answered Oct 10, 2018 at 18:00
включение ассемблерных вставок
, ‘__asm’ not supported on this architecture
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Приветствую Нужно сделать вставку на ассемблере, но компилятор ругнулся Цитата error C4235: nonstandard extension used : ‘__asm’ keyword not supported on this architecture MSDN выдал: Цитата For example, the _asm keyword is not supported for the Itanium Processor Family (IPF) compiler. All assembly code must be written in a separate file or should be used through an intrinsic. See Intrinsics Available on Intel 64-bit Platforms for more information. использовать встроенные функции мне кажется негибко (не могу манипулировать с регистрами) |
trainer |
|
Напиши маленький тестовый проектик, заставь VS выдать по нему ассемблерный код и посмотри, что там и как. В C-ном исходнике тебе понадобится прототип функции. Вызывать — так же, как и любую другую функцию. |
Fireman |
|
а если мой код ассемблерный на функцию не тянет — я хотел некоторые вычисления внутри функции на нем сделать |
trainer |
|
Цитата Fireman @ 21.03.06, 08:33 а дальше что? Компилируешь проект и получаешь исполнимый файл. Цитата Fireman @ 21.03.06, 08:33 внутрб функции пихнуть Внутрь функции не пихнешь. Это будет самостоятельная функция, написанная на ассемблере. |
Fireman |
|
дело в том что у меня это в классе происходит, ну по идее я могу в функцию передать некоторые указатели на данные, но все же и еще — если пользоваться интристик функциями — смогу ли я манипулировать регистрами? |
trainer |
|
Делаешь что-то.asm, где пишешь реализацию функции, подключаешь в проект Сообщение отредактировано: trainer — 21.03.06, 10:44 |
Fireman |
|
Так вот про реализацию
mov r12, sp stmdb sp!, {r0, r1} stmdb sp!, {r12, lr} sub sp, sp, #4 // тут код ldr r0, [sp] add sp, sp, #4 ldmia sp, {sp, pc} надо ведь дописать как функция называется и т.п. |
trainer |
|
Цитата Fireman @ 21.03.06, 10:55 надо ведь дописать как функция называется и т.п. Ну да. Напиши ее на C, сконвертируй с помощью компилятора в ассемблер и получишь все необходимое. Полное декорированное имя функции, код входа в функцию и выходя из нее. Потом подменяешь тело и используешь(удалив реализацию на C). А заодно посмотришь, стоит ли овчинка выделки? Кстати, есть Intel C++ для XScale под WinCE. Сообщение отредактировано: trainer — 22.03.06, 06:12 |
Fireman |
|
Ну я чуть другое имел в виду
.386 .model flat, c .code sieve PROC uses ebx mov eax, 0 RET sieve ENDP end это для Itanium было сделано (ну и x86 тоже переваривает) P.S. кстати Visual Studio .NET не выдает ошибки в asm файле (просто сообщаяет о факте ошибки, но где и какая — молчок) — это не исправить? Добавлено 22.03.06, 07:46 Сообщение отредактировано: Fireman — 22.03.06, 07:46 |
trainer |
|
Цитата Fireman @ 22.03.06, 07:14 Ну я чуть другое имел в виду А я именно это и имел в виду.
int min_func(int a, int b) { return a-b; } компилируешь не в объектный код, а в ассемблерный и видишь, что там должно быть. Включая полное декорированное имя функции, код входа в функцию и выхода из нее. Я сам так делал, например, с IAR EWAVR — там у меня весь проект был написан на C, только один обработчик прерывания на ассемблере. Сообщение отредактировано: trainer — 22.03.06, 08:13 |
Fireman |
|
int min_func(int a, int b) { 00011000 mov r12, sp 00011004 stmdb sp!, {r0, r1} 00011008 stmdb sp!, {r12, lr} 0001100C sub sp, sp, #4 return a-b; 00011010 ldr r2, a 00011014 ldr r3, b 00011018 sub r3, r2, r3 0001101C str r3, [sp] } 00011020 ldr r0, [sp] 00011024 add sp, sp, #4 00011028 ldmia sp, {sp, pc} int main(void) { 0001102C sub sp, sp, #4 return 0; 00011030 mov r3, #0 00011034 str r3, [sp] } но это же не то я про то что он даже не пытается .asm файл откомпилировать, хотя тот стоит в проекте |
trainer |
|
Это ты чего-то не то сделал. Вот что у меня получилось в VS.NET(под x86):
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077 TITLE .sep_func.cpp .386P include listing.inc if @Version gt 510 .model FLAT else _TEXT SEGMENT PARA USE32 PUBLIC ‘CODE’ _TEXT ENDS _DATA SEGMENT DWORD USE32 PUBLIC ‘DATA’ _DATA ENDS CONST SEGMENT DWORD USE32 PUBLIC ‘CONST’ CONST ENDS _BSS SEGMENT DWORD USE32 PUBLIC ‘BSS’ _BSS ENDS $$SYMBOLS SEGMENT BYTE USE32 ‘DEBSYM’ $$SYMBOLS ENDS $$TYPES SEGMENT BYTE USE32 ‘DEBTYP’ $$TYPES ENDS _TLS SEGMENT DWORD USE32 PUBLIC ‘TLS’ _TLS ENDS ; COMDAT ?min_func@@YAHHH@Z _TEXT SEGMENT PARA USE32 PUBLIC ‘CODE’ _TEXT ENDS sxdata SEGMENT DWORD USE32 ‘SXDATA’ sxdata ENDS FLAT GROUP _DATA, CONST, _BSS ASSUME CS: FLAT, DS: FLAT, SS: FLAT endif INCLUDELIB LIBCD INCLUDELIB OLDNAMES PUBLIC ?min_func@@YAHHH@Z ; min_func EXTRN __RTC_InitBase:NEAR EXTRN __RTC_Shutdown:NEAR ; COMDAT rtc$IMZ ; File c:programmerprojectstesttest001sep_func.cpp rtc$IMZ SEGMENT __RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase rtc$IMZ ENDS ; COMDAT rtc$TMZ rtc$TMZ SEGMENT __RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown ; Function compile flags: /Odt /RTCsu /ZI rtc$TMZ ENDS ; COMDAT ?min_func@@YAHHH@Z _TEXT SEGMENT _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 ?min_func@@YAHHH@Z PROC NEAR ; min_func, COMDAT ; 1 : int min_func(int a, int b) { push ebp mov ebp, esp sub esp, 192 ; 000000c0H push ebx push esi push edi lea edi, DWORD PTR [ebp-192] mov ecx, 48 ; 00000030H mov eax, -858993460 ; ccccccccH rep stosd ; 2 : return a-b; mov eax, DWORD PTR _a$[ebp] sub eax, DWORD PTR _b$[ebp] ; 3 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ?min_func@@YAHHH@Z ENDP ; min_func _TEXT ENDS END Вот у тебя должно быть примерно такое же, но для XScale Добавлено 22.03.06, 10:11 Добавлено 22.03.06, 10:15 |
Fireman |
|
так в том то и дело что ARM это не 386 сейчас получил такое Цитата fatal error LNK1112: module machine type ‘X86’ conflicts with target machine type ‘THUMB’ и как с этим бороться не знаю в .h у меня
void Example1(void); а в .asm
_text SEGMENT OPTION LANGUAGE:c Example1 PROC FRAME ; rest of function … ret Example1 ENDP _text ENDS END |
trainer |
|
Цитата Fireman @ 22.03.06, 11:00 так в том то и дело что ARM это не 386 Ну так у меня просто нет под рукой компилятора под XScale. |
Fireman |
|
а как его включить то? в этом то вся и беда — не могу задать ARM код |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- C/C++: Прочее
- Следующая тема
[ Script execution time: 0,0493 ] [ 16 queries used ] [ Generated: 9.02.23, 12:13 GMT ]
Started by
koe, February 6, 2008
7 posts in this topic
..clientmemcpy_amd.cpp(90) : error C4235: nonstandard extension used : ‘__asm’ keyword not supported on this architecture
Помогите скомпилировать под x64 amd (Vista x64 Studio 2008 TS) компилируется под x86 нормально, под x64 вышеназванная ошибка.
Share this post
Link to post
Буду передать запрос на разработчики, но лично я не думаю что решение будет легко, если возможно вообще.
Share this post
Link to post
По сути надо добавить заголовок memory.h, закоментировать в stdinc.h оптимизатор memcpy_amd.h и блок:
#undef memcpy #define memcpy memcpy2 #undef memset #define memset memset2 #undef memzero #define memzero memzero2
Но т.к. стандартной memzero нет, её надо будет переписать через стандартную memset. И затем переопределить memcpy2, memset2 и memzero2 как:
#define memcpy2 memcpy #define memset2 memset #define memzero2 memzero
Если что-то из этого не понятно — лучше забить на компиляцию под 64 бит.
Share this post
Link to post
По сути надо добавить заголовок memory.h, закоментировать в stdinc.h оптимизатор memcpy_amd.h и блок:
#undef memcpy
#define memcpy memcpy2
#undef memset
#define memset memset2
#undef memzero
#define memzero memzero2Но т.к. стандартной memzero нет, её надо будет переписать через стандартную memset. И затем переопределить memcpy2, memset2 и memzero2 как:
#define memcpy2 memcpy
#define memset2 memset
#define memzero2 memzeroЕсли что-то из этого не понятно — лучше забить на компиляцию под 64 бит.
Excuse for commenting here directly, but that solution is not good at all… here is why it doesn’t work and what should be done to preserve same optimized code and functionality that in 32bit (because those asm blocks that fail for 64bit are optimized for performance).
When targeting x64 platforms in Visual Studio 2005 or later, programmers are no longer able to use inline assembly code as they did for 32-bit code. This forces the programmer to either rely on C/C++ code using intrinsics, or to tediously create a 64-bit MASM (.asm) version of the function.
Share this post
Link to post
I know that removing of optimization routine is a dirty hack but in present time I see no other way to compile code as x64 executable.
PS: By the way are intrinsic functions from latest VS really slow down the code? As I see from the headers they use SSE too.
Share this post
Link to post
PS: By the way are intrinsic functions from latest VS really slow down the code? As I see from the headers they use SSE too.
SSE perhaps, but what about other optimizations…
Share this post
Link to post
Excuse for commenting here directly, but that solution is not good at all… here is why it doesn’t work and what should be done to preserve same optimized code and functionality that in 32bit (because those asm blocks that fail for 64bit are optimized for performance).
When targeting x64 platforms in Visual Studio 2005 or later, programmers are no longer able to use inline assembly code as they did for 32-bit code. This forces the programmer to either rely on C/C++ code using intrinsics, or to tediously create a 64-bit MASM (.asm) version of the function.
Извините на директний коментар, но ето решение вообще плохо… смотрите почему оно не работает и что нужно сделать для сохранения оптимизацией в кода и функкциональност на 32 бит (потому что ети asm частици, неработающих под 64 бит — оптимизирование для производительност).
Когда приступаем к х64 платформьiй на VS 2005 или позднее, програмисти болше не могут ползвать «?встроеннои в реду-inline?» асемблаторнии код, как они делали для 32-битовой код. Ето задолжает програмист либо лежат на С/С++ код, с употребления
Share this post
Link to post
06-17-2018, 08:22 |
||||
|
||||
How to inline x64 asm in vs2017 ? Hi nonstandard extension used: ‘__asm’ keyword not supported on this architecture __________________ All about software security references https://t.me/securebyte
Last edited by Mahmoudnia; 06-17-2018 at 15:36.
|
06-17-2018, 09:53 |
||||
|
||||
There is no x64 inline assembly with the Microsoft compiler. Quote: One of the constraints for the x64 compiler is to have no inline assembler support. This means that functions that cannot be written in C or C++ will either have to be written as subroutines or as intrinsic functions supported by the compiler. Certain functions are performance sensitive while others are not. Performance-sensitive functions should be implemented as intrinsic functions. |
The Following 2 Users Say Thank You to deepzero For This Useful Post: |
06-17-2018, 14:31 |
||||
|
||||
http://masm32.com/board/index.php?topic=4211.0 maybe useful in check options. |
The Following 2 Users Say Thank You to user1 For This Useful Post: |
06-18-2018, 02:16 |
||||
|
||||
You have several options. |
The Following 2 Users Say Thank You to Archer For This Useful Post: |
06-18-2018, 02:22 |
||||
|
||||
@Archer __________________ All about software security references https://t.me/securebyte |
06-18-2018, 03:08 |
|||
|
|||
Or as a fourth option since it has yet to be mentioned, write a tool which at compile time extracts all inline code from C modules intended for x64 compilation, put them in an .asm file with some type of label or function definition, compile them, replace the C code with an appropriate control flow transfer, and so forth. Unfortunately, nothing will be exactly equivalent mentioned so far in MSVC as the control flow transfer is pretty hard to avoid. Best yet might be to keep requesting MS to make the long overdo change as a developer feedback or feature request. |
06-18-2018, 14:54 |
|||
|
|||
Two ways: — Intrinsics https://msdn.microsoft.com/en-us/library/26td21ds.aspx Best Regards, |
The Following 2 Users Say Thank You to Evilcry For This Useful Post: |
06-18-2018, 19:35 |
|||
|
|||
But since you are not linking the .asm inline, there are excessive call or jump statements emitted. The best would be if MS were to add it. |
06-20-2018, 01:34 |
|||
|
|||
Does one call or jump really matter? |
The Following User Says Thank You to gigaman For This Useful Post: |
06-20-2018, 05:38 |
|||
|
|||
It matters because its very convenient to program like this. By having to call/return or jump/jump or what have you (also don’t forget all the stack setup and cleanup), it forces calling conventions and requires the parameters to be dealt with and such. Yes the MS implementation is not as clever as in GCC/GAS where you can really customize details of the behavior. I agree for optimization its a lame point as you would better be off with pure asm or optimized C rather than a mix and match without sophisticated inline-ing support. Further its easier to write portable 64/32 bit code without calling conventions and clever use of macros, as the calling conventions are so different you have to use different assembly instructions (registers vs stack). A C function can modify itself in memory also using clever tricks with inline assembler which has its obfuscation or other uses. But I suppose this discussion is easily already documented: Quote: https://msdn.microsoft.com/en-us/library/80ccffx3.aspx Quote: Advantages of Inline Assembly So optimization is on the list after all |
The Following User Says Thank You to chants For This Useful Post: |
06-21-2018, 01:44 |
||||
|
||||
While you can’t use inline asm, you can link ASM files into your program and use a separate compiler such as MASM to build .asm files with your project. Visual Studio has support for this built-in. If you absolutely need inline asm you can use a different compiler/linker. |
06-21-2018, 21:11 |
|||
|
|||
Well it looks like it will not happen anytime either. Unless we all get together to vote it to the top. Difficult to reason about proving correctness in the compiler I suppose Quote: https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/2609085-support-inline-assembler-on-c-64-bit Quote: DECLINED· Admin |
The Following User Says Thank You to chants For This Useful Post: |
07-17-2018, 04:00 |
|||
|
|||
Just create a .ASM file, change the build rule to MASM, define the subroutine and call it from the C file. masm.asm Quote: .CODE PUBLIC MyAsmRoutine MyAsmRoutine PROC ChangeRaxRoutine PROC END file.c Quote: void MyAsmRoutine(PVOID pFunc); int main()
Last edited by Avalon; 07-17-2018 at 04:05.
|
The Following User Says Thank You to Avalon For This Useful Post: |
07-17-2018, 06:56 |
||||
|
||||
@avalon Change RaxRoutine PROC …. public ChangeRaxRoutine ChangeRaxRoutine proc
__________________ |
The Following User Says Thank You to Insid3Code For This Useful Post: |
07-18-2018, 19:23 |
|||
|
|||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
#include "stdafx.h" #include "xrTheora_Surface_mmx.h" #pragma warning( disable : 4731 ) #pragma pack( push ) #pragma pack( 1 ) typedef tv_sshort tv_sshort_tables[ 256 ][ 4 ]; #pragma pack( pop ) /* //. width_diff = surface_width - theora_width u32 pos = 0; for (u32 h=0; h<height; ++h){ u8* Y = yuv.y+yuv.y_stride*h; u8* U = yuv.u+yuv.uv_stride*(h/uv_h); u8* V = yuv.v+yuv.uv_stride*(h/uv_h); for (u32 w=0; w<width; ++w){ u8 y = Y[w]; u8 u = U[w/uv_w]; u8 v = V[w/uv_w]; int C = y - 16; int D = u - 128; int E = v - 128; int R = clampr(( 298 * C + 409 * E + 128) >> 8,0,255); int G = clampr(( 298 * C - 100 * D - 208 * E + 128) >> 8,0,255); int B = clampr(( 298 * C + 516 * D + 128) >> 8,0,255); data[++pos] = color_rgba(R,G,B,255); if(w==(width-1)) pos += width_diff; } } */ lp_tv_uchar tv_yuv2argb( lp_tv_uchar argb_plane , tv_slong argb_width , tv_slong argb_height , lp_tv_uchar y_plane , tv_slong y_width , tv_slong y_height , tv_slong y_stride , lp_tv_uchar u_plane , lp_tv_uchar v_plane , tv_slong uv_width , tv_slong uv_height , tv_slong uv_stride, tv_slong width_diff ) { tv_sshort_tables ttl; __asm{ push ebx // helper constants mov esi,-14487936 mov edi,-5822464 mov ecx,-2785792 mov edx,-14496256 lea ebx,DWORD PTR [ttl + 2] // building helper tables ALIGN 4 _tb_loop: mov eax,esi sar eax,16 mov WORD PTR [ebx-2],ax mov eax,edi sar eax,16 mov WORD PTR [ebx+0],ax mov eax,ecx sar eax,16 mov WORD PTR [ebx+2],ax mov eax,edx sar eax,16 mov WORD PTR [ebx+4],ax add esi,113443 add edi,45744 add ecx,22020 add edx,113508 add ebx,4 * ( TYPE tv_sshort ) cmp esi,14553472 jl _tb_loop pop ebx } lp_tv_uchar line1 = argb_plane; lp_tv_uchar line2 = line1 + 4 * argb_width; lp_tv_uchar y1 = y_plane; lp_tv_uchar y2 = y1 + y_stride; lp_tv_uchar u = u_plane; lp_tv_uchar v = v_plane; int nTempX; int nTempY; int nTempX_; for( nTempY = 0 ; nTempY < argb_height ; nTempY += 2 ){ for( nTempX = 0 ; nTempX < argb_width ; nTempX += 4 ){ nTempX_ = nTempX >> 1; __asm{ push ebx ; mov eax,DWORD PTR y1 ; eax = y1 mov ebx,DWORD PTR y2 ; ebx = y2 mov edi,DWORD PTR v ; edi = v add eax,DWORD PTR nTempX ; eax = y1 + nTempX add ebx,DWORD PTR nTempX ; ebx = y2 + nTempX pxor mm2,mm2 ; mm2 = 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 add edi,DWORD PTR nTempX_ ; edi = v + nTempX_ lea esi,DWORD PTR ttl ; esi = ttl movd mm0,DWORD PTR [eax] ; mm0 = 0 | 0 | 0 | 0 | nY4 | nY3 | nY2 | nY1 movd mm1,DWORD PTR [ebx] ; mm1 = 0 | 0 | 0 | 0 | nY8 | nY7 | nY6 | nY5 movzx edx,DWORD PTR [edi] ; edx = V1 movzx ecx,DWORD PTR [edi+1] ; ecx = V2 punpcklbw mm0,mm2 ; mm0 = nY4 | nY3 | nY2 | nY1 punpcklbw mm1,mm2 ; mm1 = nY8 | nY7 | nY6 | nY5 pinsrw mm4,WORD PTR [esi+edx*8+0],00000000b ; mm4 = 0 | 0 | 0 | ttl[nV1][0] pinsrw mm5,WORD PTR [esi+ecx*8+0],00000000b ; mm5 = 0 | 0 | 0 | ttl[nV2][0] movq mm3,mm0 ; mm3 = nY4 | nY3 | nY2 | nY1 mov edi,DWORD PTR u ; edi = u punpckldq mm3,mm1 ; mm3 = nY6 | nY5 | nY2 | nY1 punpckhdq mm0,mm1 ; mm0 = nY8 | nY7 | nY4 | nY3 pshufw mm4,mm4,00000000b ; mm4 = ttl[nV1][0] | ttl[nV1][0] | ttl[nV1][0] | ttl[nV1][0] pshufw mm5,mm5,00000000b ; mm5 = ttl[nV2][0] | ttl[nV2][0] | ttl[nV2][0] | ttl[nV2][0] add edi,DWORD PTR nTempX_ ; edi = u + nTempX_ paddsw mm4,mm3 ; mm4 = P6.R | P5.R | P2.R | P1.R paddsw mm5,mm0 ; mm5 = P8.R | P7.R | P4.R | P3.R pinsrw mm1,WORD PTR [esi+edx*8+2],00000000b ; mm1 = 0 | 0 | 0 | ttl[nV1][1] pinsrw mm2,WORD PTR [esi+ecx*8+2],00000000b ; mm2 = 0 | 0 | 0 | ttl[nV2][1] movq mm6,mm3 ; mm6 = nY6 | nY5 | nY2 | nY1 movq mm7,mm0 ; mm7 = nY8 | nY7 | nY4 | nY3 movzx edx,DWORD PTR [edi] ; edx = U1 movzx ecx,DWORD PTR [edi+1] ; ecx = U2 pshufw mm1,mm1,00000000b ; mm1 = ttl[nV1][1] | ttl[nV1][1] | ttl[nV1][1] | ttl[nV1][1] pshufw mm2,mm2,00000000b ; mm2 = ttl[nV2][1] | ttl[nV2][1] | ttl[nV2][1] | ttl[nV2][1] psubsw mm6,mm1 ; mm6 = nY6 - ttl[nV1][1] | nY5 - ttl[nV1][1] | nY2 - ttl[nV1][1] | nY1 - ttl[nV1][1] psubsw mm7,mm2 ; mm7 = nY8 - ttl[nV2][1] | nY7 - ttl[nV2][1] | nY4 - ttl[nV2][1] | nY3 - ttl[nV2][1] pinsrw mm1,WORD PTR [esi+edx*8+4],00000000b ; mm1 = 0 | 0 | 0 | ttl[nU1][2] pinsrw mm2,WORD PTR [esi+ecx*8+4],00000000b ; mm2 = 0 | 0 | 0 | ttl[nU2][2] pshufw mm1,mm1,00000000b ; mm1 = ttl[nU1][2] | ttl[nU1][2] | ttl[nU1][2] | ttl[nU1][2] pshufw mm2,mm2,00000000b ; mm2 = ttl[nU2][2] | ttl[nU2][2] | ttl[nU2][2] | ttl[nU2][2] psubsw mm6,mm1 ; mm6 = P6.G | P5.G | P2.G | P1.G psubsw mm7,mm2 ; mm7 = P8.G | P7.G | P4.G | P3.G pinsrw mm1,WORD PTR [esi+edx*8+6],00000000b ; mm1 = 0 | 0 | 0 | ttl[nU1][3] pinsrw mm2,WORD PTR [esi+ecx*8+6],00000000b ; mm2 = 0 | 0 | 0 | ttl[nU2][3] pshufw mm1,mm1,00000000b ; mm1 = ttl[nU1][3] | ttl[nU1][3] | ttl[nU1][3] | ttl[nU1][3] pshufw mm2,mm2,00000000b ; mm2 = ttl[nU2][3] | ttl[nU2][3] | ttl[nU2][3] | ttl[nU2][3] paddsw mm3,mm1 ; mm3 = P6.B | P5.B | P2.B | P1.B paddsw mm0,mm2 ; mm0 = P8.B | P7.B | P4.B | P3.B // we have ; mm4 = P6.R | P5.R | P2.R | P1.R ; mm6 = P6.G | P5.G | P2.G | P1.G ; mm3 = P6.B | P5.B | P2.B | P1.B ; mm5 = P8.R | P7.R | P4.R | P3.R ; mm7 = P8.G | P7.G | P4.G | P3.G ; mm0 = P8.B | P7.B | P4.B | P3.B // saturation packuswb mm4,mm5 ; mm4 = P8.R | P7.R | P4.R | P3.R | P6.R | P5.R | P2.R | P1.R packuswb mm6,mm7 ; mm6 = P8.G | P7.G | P4.G | P3.G | P6.G | P5.G | P2.G | P1.G packuswb mm3,mm0 ; mm3 = P8.B | P7.B | P4.B | P3.B | P6.B | P5.B | P2.B | P1.B // calculating effective store address mov esi,DWORD PTR line1 ; esi = line1 mov edi,DWORD PTR line2 ; edi = line2 // we want ;px1 = 00 | P2.R | P2.G | P2.B | 00 | P1.R | P1.G | P1.B | ;px2 = 00 | P4.R | P4.G | P4.B | 00 | P3.R | P3.G | P3.B | ;px3 = 00 | P6.R | P6.G | P6.B | 00 | P5.R | P5.G | P5.B | ;px4 = 00 | P8.R | P8.G | P8.B | 00 | P7.R | P7.G | P7.B | // Oh, real sex! pcmpeqd mm0,mm0 ; mm0 = 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 movq mm5,mm6 ; mm5 = P8.G | P7.G | P4.G | P3.G | P6.G | P5.G | P2.G | P1.G movq mm7,mm3 ; mm7 = P8.B | P7.B | P4.B | P3.B | P6.B | P5.B | P2.B | P1.B punpcklbw mm5,mm0 ; mm5 = 0 | P6.G | 0 | P5.G | 0 | P2.G | 0 | P1.G punpcklbw mm7,mm4 ; mm7 = P6.R | P6.B | P5.R | P5.B | P2.R | P2.B | P1.R | P1.B movq mm1,mm7 ; mm1 = P6.R | P6.B | P5.R | P5.B | P2.R | P2.B | P1.R | P1.B punpcklbw mm7,mm5 ; mm7 = 0 | P2.R | P2.G | P2.B | 0 | P1.R | P1.G | P1.B // px1 punpckhbw mm1,mm5 ; mm1 = 0 | P6.R | P6.G | P6.B | 0 | P5.R | P5.G | P5.B // px3 movq mm2,mm6 ; mm2 = P8.G | P7.G | P4.G | P3.G | P6.G | P5.G | P2.G | P1.G movq mm5,mm3 ; mm5 = P8.B | P7.B | P4.B | P3.B | P6.B | P5.B | P2.B | P1.B punpckhbw mm2,mm0 ; mm2 = 0 | P8.G | 0 | P7.G | 0 | P4.G | 0 | P3.G punpckhbw mm5,mm4 ; mm5 = P8.R | P8.B | P7.R | P7.B | P4.R | P4.B | P3.R | P3.B movq mm0,mm5 ; mm0 = P8.R | P8.B | P7.R | P7.B | P4.R | P4.B | P3.R | P3.B punpckhbw mm5,mm2 ; mm5 = 0 | P8.R | P8.G | P8.B | 0 | P7.R | P7.G | P7.B // px4 punpcklbw mm0,mm2 ; mm0 = 0 | P4.R | P4.G | P4.B | 0 | P3.R | P3.G | P3.B // px2 // storing using non-temporal hint movntq MMWORD PTR [esi+0],mm7 ; movntq MMWORD PTR [esi+8],mm0 ; movntq MMWORD PTR [edi+0],mm1 ; movntq MMWORD PTR [edi+8],mm5 ; // we are the champions pop ebx ; } line1 += 16; line2 += 16; } y1 += 2 * y_stride; y2 = y1 + y_stride; u += uv_stride; v += uv_stride; line1 += 4 * argb_width; line2 = line1 + 4 * argb_width; } __asm{ sfence ; emms ; } return argb_plane; } // tv_yuv2argb #pragma warning( default : 4731 ) |