无法编译内联汇编
Can't compile inline assembly
我无法在 Visual Studio 2017 中编译汇编文件。
我不确定这是由于 visual studio 还是因为我在代码中犯了一些错误,请帮助我。
我有一个 c++ 主文件,我在其中进行调用:
#include "stdafx.h"
#include "myStruct.h"
extern "C" __int64 CalcStructSum_(const myStruct *kekStruct);
int _tmain(int argc, _TCHAR* argv[])
{
myStruct kek;
kek.Val8 = 8;
kek.Val16 = 16;
kek.Val32 = 32;
kek.Val64 = 64;
__int64 summe = CalcStructSum_(&kek);
printf("summe betraegt: %d", summe);
getchar();
return 0;
}
mystruct.h :
#pragma once
typedef struct
{
__int8 Val8;
__int8 Pad8;
__int16 Val16;
__int32 Val32;
__int64 Val64;
}myStruct;
这里的汇编等价物:
myStruct struct
Val8 byte ?
Pad8 byte ?
Val16 word ?
Val32 dword ?
Val64 qword ?
myStruct ends
这里是汇编文件:
.model flat,c
include myStruct_.inc
.code
;prolog and function start
CalcStructSum_ proc
push ebp
mov ebp,esp
push ebx
push esi
; das struct liegt auf dem stack
; alle felder wurden auf 32 bit sign-extended
; in esi kommt anfang des speicherbereichs rein
; später wird quasi [basereg + dispatch] daraus interpretiert
mov esi, [ebp+8] ; get a pointer to "mystruct"
; load 8- and 16bit sources into 32bit registers (movsx)
; this is necassery to load struct-fields from the stack
movsx eax, byte ptr [esi + myStruct.Val8] ; [baser. + disp]
movsx ecx, word ptr [esi + myStruct.Val16]
add eax, ecx
; now sign-extend eax register to 64bit
; high part: edx , low part: eax
cdq
;save result for later
mov ebx, eax
mov ecx, edx
; now load the int-part of the struct and add it
; (it must be sign-extended to edx:eax again)
mov eax, [esi + myStruct.Val32]
cdq
; (the high-part must be added with carry, if overflown)
add eax, ebx
adc edx, ecx
; now, get the long from stack
add eax, dword ptr [esi + myStruct.Val64] ; low part
adc edx, dwprd ptr [esi + myStruct.Val64 + 4] ; high part
; we now have the sum of all structure fields in the register pair edx:eax
pop esi
pop ebx
pop ebp
ret
CalcStructSum_ endp
end
此外,我像这样将文件包含在我的资源管理器 window 中(当然,还设置了构建依赖项):
我也尝试使用 ml.exe 从 powershell 进行组装,但也没有成功。
另外,如果有人能指出一个简单的方法来捕获 ml.exe 的输出,那就太好了,它在执行后立即消失(我是一个 cmd-noob)。
最后,我尝试将文件置于 ANSI 模式,但这根本不是问题,我只是通读了旧的 Whosebug 答复者。
我错过了什么?我应该回到 VS2010 吗?或者它只是一个愚蠢的语法错误?这真的把我吓坏了,因为这么简单的概念验证程序应该不难写 -.-
好的,问题已解决:
原来是第 50 行的错字 ["dwprd" 而不是 "dword" ]。
已修复并解决。
如果有人遇到像我这样的情况,他们就是找不到 assembler / IDE 提供的任何有用提示,那么我是这样找到解决方案的:
[ 在 windows OS ]
- 打开资源管理器 window 并搜索 "ml.exe"(需要很长时间)
- 最佳做法是为该目录建立硬链接以便于使用
- assemble 一次只有一个文件 ml.exe,使用标志 "c" 这样链接器将保持冷静和安静 [因为 c 用于 "don't link at all"]
- "ml.exe -c" 将提供一些错误输出(对我来说是 "unknown command dwprd" 或类似的东西),如果成功
也会创建一个 .obj 文件
- 修复所有出现的错误和错误后,返回 Visual Studio 并编译,如果您仍然没有运气,请尝试将 assembled .obj 文件移动到 VS 项目文件夹。
我无法在 Visual Studio 2017 中编译汇编文件。 我不确定这是由于 visual studio 还是因为我在代码中犯了一些错误,请帮助我。
我有一个 c++ 主文件,我在其中进行调用:
#include "stdafx.h"
#include "myStruct.h"
extern "C" __int64 CalcStructSum_(const myStruct *kekStruct);
int _tmain(int argc, _TCHAR* argv[])
{
myStruct kek;
kek.Val8 = 8;
kek.Val16 = 16;
kek.Val32 = 32;
kek.Val64 = 64;
__int64 summe = CalcStructSum_(&kek);
printf("summe betraegt: %d", summe);
getchar();
return 0;
}
mystruct.h :
#pragma once
typedef struct
{
__int8 Val8;
__int8 Pad8;
__int16 Val16;
__int32 Val32;
__int64 Val64;
}myStruct;
这里的汇编等价物:
myStruct struct
Val8 byte ?
Pad8 byte ?
Val16 word ?
Val32 dword ?
Val64 qword ?
myStruct ends
这里是汇编文件:
.model flat,c
include myStruct_.inc
.code
;prolog and function start
CalcStructSum_ proc
push ebp
mov ebp,esp
push ebx
push esi
; das struct liegt auf dem stack
; alle felder wurden auf 32 bit sign-extended
; in esi kommt anfang des speicherbereichs rein
; später wird quasi [basereg + dispatch] daraus interpretiert
mov esi, [ebp+8] ; get a pointer to "mystruct"
; load 8- and 16bit sources into 32bit registers (movsx)
; this is necassery to load struct-fields from the stack
movsx eax, byte ptr [esi + myStruct.Val8] ; [baser. + disp]
movsx ecx, word ptr [esi + myStruct.Val16]
add eax, ecx
; now sign-extend eax register to 64bit
; high part: edx , low part: eax
cdq
;save result for later
mov ebx, eax
mov ecx, edx
; now load the int-part of the struct and add it
; (it must be sign-extended to edx:eax again)
mov eax, [esi + myStruct.Val32]
cdq
; (the high-part must be added with carry, if overflown)
add eax, ebx
adc edx, ecx
; now, get the long from stack
add eax, dword ptr [esi + myStruct.Val64] ; low part
adc edx, dwprd ptr [esi + myStruct.Val64 + 4] ; high part
; we now have the sum of all structure fields in the register pair edx:eax
pop esi
pop ebx
pop ebp
ret
CalcStructSum_ endp
end
此外,我像这样将文件包含在我的资源管理器 window 中(当然,还设置了构建依赖项):
我也尝试使用 ml.exe 从 powershell 进行组装,但也没有成功。 另外,如果有人能指出一个简单的方法来捕获 ml.exe 的输出,那就太好了,它在执行后立即消失(我是一个 cmd-noob)。
最后,我尝试将文件置于 ANSI 模式,但这根本不是问题,我只是通读了旧的 Whosebug 答复者。
我错过了什么?我应该回到 VS2010 吗?或者它只是一个愚蠢的语法错误?这真的把我吓坏了,因为这么简单的概念验证程序应该不难写 -.-
好的,问题已解决:
原来是第 50 行的错字 ["dwprd" 而不是 "dword" ]。
已修复并解决。 如果有人遇到像我这样的情况,他们就是找不到 assembler / IDE 提供的任何有用提示,那么我是这样找到解决方案的:
[ 在 windows OS ]
- 打开资源管理器 window 并搜索 "ml.exe"(需要很长时间)
- 最佳做法是为该目录建立硬链接以便于使用
- assemble 一次只有一个文件 ml.exe,使用标志 "c" 这样链接器将保持冷静和安静 [因为 c 用于 "don't link at all"]
- "ml.exe -c" 将提供一些错误输出(对我来说是 "unknown command dwprd" 或类似的东西),如果成功 也会创建一个 .obj 文件
- 修复所有出现的错误和错误后,返回 Visual Studio 并编译,如果您仍然没有运气,请尝试将 assembled .obj 文件移动到 VS 项目文件夹。