如何解决使用 NASM 和 YASM 的“两者”进行 Win64 编程
我正在研究如何在 Windows 上编写 x86-64 汇编程序。
我尝试了两个汇编程序——NASM 和 YASM。但是,它们都缺少功能:
- 对于每个非叶函数,Windows 都需要 stack unwind information。 YASM supports macros to generate them;但是,它们应该在 NASM 上通过“bit-banging”来构建。
- 由于 YASM 是从 NASM 分支而来的,因此 NASM 添加了预处理器指令,例如
%defstr
或%deftok
。 YASM(目前)不支持这些。
Some user 建议仅使用 NASM 作为预处理器,然后将结果提供给 YASM。因此,我创建了以下“构建脚本”,它现在似乎可以工作。
@echo off
if "%VSCMD_VER%" == "" call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
@echo on
("D:\nasm-2.15.05\nasm.exe" -E demo.asm -o demo.asm.p
".\yasm-1.3.0-win64.exe" -fwin64 -gcv8 -l demo.lst -o demo.obj demo.asm.p
link.exe /nologo /debug:full /debugtype:cv,pdata,fixup demo.obj)
然而,我觉得自己如履薄冰,一旦尝试做更复杂的事情,我可能会崩溃。
问题::
- 当前方案的缺点是什么?有没有这个方案的一些非工作示例?
- 是否可以让 NASM 宏像 YASM 一样提供堆栈展开信息?
- 我应该改用 MASM 吗? NASM/YASM 不是用于 win64 编程的正确工具吗?由于 Linux 编程,我对 NASM 语法有些熟悉,但我不确定 MASM。
作为参考,这里是我的汇编源代码——用 NASM 宏包装 UCRT vfprintf。
default rel
extern __acrt_iob_func
extern __stdio_common_vfprintf
extern ExitProcess
section .drectve
db "/subsystem:console",0
db "/defaultlib:ucrt",0
db "/defaultlib:kernel32",0
db "/entry:entry",0
%macro printf 1-*
%push printf
%assign %$index 40
mov ecx,1
call __acrt_iob_func
mov rcx,0x24
mov rdx,rax
lea r8,[%1]
xor r9,r9
lea rax,[rsp+40]
mov [rsp+32],rax
%rep %0-1
%defstr %$param %2
%substr %$reltest %$param 1,3
%if %$reltest == "rel"
lea rax,[%2]
%else
mov rax,%2
%endif
mov [rsp+%$index],rax
%assign %$index %$index+8
%rotate 1
%endrep
call __stdio_common_vfprintf
%pop
%endmacro
section .rdata
entry.str: db "The data are %d and %f and %s",0x0d,0x0a,0
entry.sstr: db "HiAll",0
section .text
global entry
proc_frame entry
push_reg rbp
alloc_stack 64
set_frame rbp,64
end_prolog
printf .str,19,23.0,rel .sstr
xor ecx,ecx
call ExitProcess
lea rsp,[rbp]
pop rbp
ret
endproc_frame
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。