目前,我正在尝试学习使用MASM64进行组装编程。我已经设法让WriteConsoleA工作了,但是我不得不尝试使用诸如printf或put之类的C函数。应该注意,我在Visual之外使用ml64.exe和link.exe,并且知道我可以成功地创建可执行文件。
这是我的代码:
includelib <kernel32.lib>
includelib <ucrt.lib>
includelib <legacy_stdio_definitions.lib>
includelib <legacy_stdio_wide_specifiers.lib>
includelib <msvcrt.lib>
includelib <vcruntime.lib>
EXTERN puts: PROC
EXTERN ExitProcess: PROC
EXTERN _CRT_INIT: PROC
.data
message BYTE "Another message! Longer this time!", 0
.code
main PROC
mov rsp, 32 ; Reserve shadow space.
call _CRT_INIT ; Here I call _CRT_INIT because I'm using a custom entry point.
; I know that this call works because commenting it out causes the
; app to crash instantly instead of opening, printing nothing, but
; still waiting a second.
add rsp, 32 ; Remove shadow space.
lea rcx, message ; Load the pointer to my message to the rcx register.
sub rsp, 32 ; Reserve shadow space.
call puts ; Call puts, I know it only takes in a BYTE PTR from the docs.
; The command windows does not crash, it stays open for a moment
; as if the message had been printed, but it is not.
; printf behaves exactly the same as puts here.
add rsp, 32 ; Remove shadow space.
xor rcx, rcx ; Zero out rcx.
call ExitProcess ; End the process.
main ENDP
END汇编程序和链接器都不会引发错误。如前所述,我的GetStdHandle和WriteConsoleA都工作得很好。我尝试过省略_CRT_INIT,但这会导致命令窗口在打开时立即崩溃。
提前谢谢你!
更新:任何未来的旅行者(或我)读到:请参阅下面@RbMm的评论,以及我的评论。结果证明printf确实起作用了--只是与WriteConsoleA不同的是,它会导致窗口终止打印完成的确切时刻!给睡眠打个电话解决了所有问题。
发布于 2022-04-03 15:47:18
谢谢@RbMm,不知道我是如何使用mov而不是sub的。奇怪的是,我试图通过一个简单地通过shell调用可执行文件的VSCode任务来运行它--结果就是将我的消息打印到控制台!由于某些原因,除非可执行文件由不同的shell调用,否则它将无法工作。
实际上,我也可以通过PowerShell调用它并获得我想要的输出。不管我是保留阴影空间还是跳过初始化CRT,情况都是如此。
单击.exe什么也不做,通过shell调用它是有效的。
https://stackoverflow.com/questions/71725085
复制相似问题