给定:带有入口点>>> meanI = np.sum(I) / float(I.size) # Exactly the same as np.mean(I) or I.mean()
>>> meanInew = np.sum(out) / float(out.size)
>>> np.isclose(meanI, meanInew) # True
我通常做
prog
或
cl.exe /MD /LD /Fe"prog.dll" /Fo"prog" "prog.c" /link ext.lib
在这两种情况下,生成的prog.dll都能正常工作。
现在我执行了以下操作来获取asm文件而不是obj文件:
cl.exe /MD /Fo"prog.obj"
cl.exe /MD /LD /Fe"prog.dll" "prog.obj" /link ext.lib
这"工作"到目前为止。但我无法弄清楚如何制作这个文件的dll。
尝试:
cl.exe /c /MD /Fa"prog"
结果:prog.dll没有入口点ml.exe /c /Cx /coff prog.asm
cl.exe /MD /LD /Fe"prog.dll" "prog.obj" /link ext.lib
再次尝试:
prog
结果:编译器警告错误的入口点_prog不是stdcall,带有12个字节的参数,编译器错误有关未解析的符号_memcpy。
问题:有没有办法将/ dev生成的/ as文件生成的asm文件编译成dll(最好是通过cl.exe,如果ml.exe不可能的话)?
答案 0 :(得分:4)
有没有办法将
EXTERN
生成的cl.exe生成的asm文件编译成dll(最好是通过cl.exe,如果ml.exe不可能的话)?
没有
我很不清楚为什么你甚至想要首先这样做。如果您的源代码是C或C ++,并且可以由MSVC编译和链接,那么引入将其转换为汇编语言和从汇编语言转换的附加中间步骤的重点是什么?只需直接使用cl.exe制作DLL。
如果你绝对必须这样做,你必须获取MSVC生成的ASM列表文件,并在通过MASM运行之前手动清理它。您可以通过关闭整个程序优化,关闭异常处理,关闭安全检查/ cookie以及向链接器指示图像不包含安全的SEH处理程序来简化此清理任务。请注意,其中一些可能会破坏或更改代码的行为!您还需要为从运行时库调用的函数添加mkdir -p /etc/marathon/ssl
cd /etc/marathon/ssl
export MARATHON_SSL_KEYSTORE_PASSWORD=jks_pass
keytool -keystore marathon.jks -deststorepass $MARATHON_SSL_KEYSTORE_PASSWORD -alias marathon -genkey -keyalg RSA
cat << EOF > /etc/default/marathon
MARATHON_SSL_KEYSTORE_PATH=/etc/marathon/ssl/marathon.jks
MARATHON_SSL_KEYSTORE_PASSWORD=$MARATHON_SSL_KEYSTORE_PASSWORD
EOF
定义。
答案 1 :(得分:1)
虽然Microsoft C编译器生成的ASM源可能不是MASM的最佳输入,但这并不意味着它不起作用,至少在某些情况下(可能不是复杂的)。如果你看一下C编译器生成的ASM文件,你会发现微软的人很难插入各种“hacky”包含,指令,手册段定义和其他MASM细节来至少给出源文件很少有机会被反馈到MASM并获得组装结果。只要你把你的期望设置得很低,我猜一个简单的C源文件,转换为ASM,然后反馈到MASM应该可以工作,如果你按顺序获得命令行选项。
您需要记住的一个警告是,如果您像使用CRT一样使用CRT(即使用memcmp),您将需要允许从相应的CRT中选择默认入口点___ DllMainCRTStartup @ 12。 LIB文件而不是指定您自己的文件。这允许在调用DllMain之前初始化CRT,以防止在调用依赖于此初始化的某些CRT函数时发生崩溃。有了这个说,Visual Studio的旧版本,比如7.1(2003),你可以不用初始化CRT,这取决于你使用的功能而不会有崩溃的风险。如果进程之前没有调用mainCRTStarttup或DllMainCRTStartup,则无论调用哪个CRT函数,C Runtime的较新版本都将抛出异常。
出于教育目的,让我们使用MSVC 7.1(2003)解决您在上面描述的入口点问题,我们不会担心初始化CRT,因此您可以明确指定自己的入口点。我认为您正在点击以下链接器警告:
warning LNK4086: entrypoint '_prog@XX' is not __stdcall with 12 bytes of arguments; image may not run
当指定自己的DLL入口点时,链接器需要一个DllMain签名(12个参数字节和stdcall,因此该函数会自行清除参数);官方是:
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
您可以实现此版本的prog.c中显示的入口点函数:
#include <Windows.h>
#include <stdio.h>
#pragma warning (disable:4100) //Warning Level 4: unreferenced formal parameter
int __stdcall prog(DWORD hInst, DWORD dwReason, DWORD dwReserved)
{
printf("Result of memcmp: %d\n",memcmp("foo","bar",3));
return(1);
}
假设您的LIB和INCLUDE环境变量已正确设置,您可以使用以下命令构建上面的源:
cl.exe /nologo /c /MD /Fa./prog.asm prog.c
link.exe /nologo /dll /subsystem:console /entry:prog prog.obj kernel32.lib
您已经知道可以使用C编译器构建原始C源代码。 关注从/ Fa选项生成的prog.asm输出文件,您可以从生成的ASM源构建DLL,如下所示:
ml.exe /c /coff /Cx prog.asm
link.exe /nologo /dll /subsystem:console /entry:prog prog.obj kernel32.lib
使用简单的控制台加载程序测试您的DLL,例如:
#include <Windows.h>
int __cdecl main(void)
{
HMODULE hLib = LoadLibrary("prog.dll");
printf("LoadLibrary result: 0x%X / code=0x%X\n",hLib,GetLastError());
}
在我的机器上,C和MASM生成的DLL都产生了以下输出:
Result of memcmp: 1
LoadLibrary result: 0x10000000 / code=0x0
Result of memcmp: 1
下面列出了编译器生成的生成的MSVC 7.1 ASM文件以供参考。注意文件如何将自己称为“列表”:)
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.6030
TITLE prog.c
.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
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
INCLUDELIB MSVCRT
INCLUDELIB OLDNAMES
_DATA SEGMENT
$SG74617 DB 'bar', 00H
$SG74618 DB 'foo', 00H
$SG74619 DB 'Result of memcmp: %d', 0aH, 00H
_DATA ENDS
PUBLIC _prog@12
EXTRN __imp__printf:NEAR
EXTRN _memcmp:NEAR
; Function compile flags: /Odt
_TEXT SEGMENT
_hInst$ = 8 ; size = 4
_dwReason$ = 12 ; size = 4
_dwReserved$ = 16 ; size = 4
_prog@12 PROC NEAR
; File prog.c
; Line 10
push ebp
mov ebp, esp
; Line 11
push 3
push OFFSET FLAT:$SG74617
push OFFSET FLAT:$SG74618
call _memcmp
add esp, 12 ; 0000000cH
push eax
push OFFSET FLAT:$SG74619
call DWORD PTR __imp__printf
add esp, 8
; Line 12
mov eax, 1
; Line 13
pop ebp
ret 12 ; 0000000cH
_prog@12 ENDP
_TEXT ENDS
END