在我的 16 位 DOS 程序中,我想使用 DOS 中断或其内部表获取程序实例的完整路径。换句话说,我正在寻找Windows API 函数GetModuleFileName(NULL)的 DOS 等效项
中断 21h/AH=60h似乎是一条正确的路线,但当程序不在当前目录中时,它会失败。我做了一个简单的测试程序:
MYTEST PROGRAM FORMAT=COM
MOV AH,60h ; TRUENAME - CANONICALIZE FILENAME OR PATH.
MOV SI,MyName
MOV DI,MyFullName
INT 21h ; Convert filename DS:SI to canonizalized name in ES:DI.
MOV AH,09h ; WRITE STRING$ TO STARNDARD OUTPUT.
MOV DX,DI
INT 21h ; Display the canonizalized name.
RET ; Terminate program.
MyName DB "MYTEST.COM",0 ; The ASCIIZ name of self (this executable program).
MyFullName DB 256 * …
Run Code Online (Sandbox Code Playgroud) 我的问题是关于EVEX编码不四舍五入语义打包REG-REG的指令允许SAE控制(禁止所有的例外),如VMIN*,*VCVTT,VGETEXT*,VREDUCE*,VRANGE*等英特尔只全声明SAE-意识512位向量长度,例如
VMINPD xmm1 {k1}{z}, xmm2, xmm3
VMINPD ymm1 {k1}{z}, ymm2, ymm3
VMINPD zmm1 {k1}{z}, zmm2, zmm3{sae}
Run Code Online (Sandbox Code Playgroud)
但我没有看到为什么SAE不能应用于使用xmm或ymm寄存器的指令的原因.
在英特尔指令集扩展编程参考的第4.6.4章中, 表4-7表示在没有舍入语义位的指令中,EVEX.b指定应用SAE,并且位EVEX.L'L指定显式向量长度:
00b: 128bit (XMM)
01b: 256bit (YMM)
10b: 512bit (ZMM)
11b: reserved
Run Code Online (Sandbox Code Playgroud)
所以他们的组合应该是合法的.
然而,NASM汇编vminpd zmm1,zmm2,zmm3,{sae}
为62F1ED185DCB,即EVEX.L'L = 00b,EVEX.b = 1,由NDISASM 2.12反汇编为vminpd xmm1,xmm2,xmm3
NASM拒绝组装vminpd ymm1,ymm2,ymm3,{sae}
,NDISASM将62F1ED385DCB(EVEX.L'L = 01b,EVEX.b = 1)拆解为vminpd xmm1,xmm2,xmm3
我想知道Knights Landing CPU是如何执行的VMINPD ymm1, ymm2, ymm3{sae}
(组装为62F1ED385DCB,EVEX.L'L = 01b,EVEX.b = 1):
让我们MOV EAX,[0xFFFFFFFF]
以64位模式将指令编码为67A1FFFFFFFF
(有效地址大小由67前缀从默认的64位切换为32位)。
英特尔指令参考手册(从2015年12月起,文档订购号:325383-057US)在第Vol。2A 2-11说:
2.2.1.3
64位模式下的位移寻址使用现有的32位ModR / M和SIB编码。ModR / M和SIB大小不变。它们保留为8位或32位,并被符号扩展为64位。
这表明应该对32bit位移进行符号扩展,但是我不确定这是否也涉及特殊的moffs寻址模式。英特尔在下一页上说:
2.2.1.6 RIP相对寻址
RIP相对寻址是通过64位模式而不是64位地址大小启用的。地址大小前缀的使用不会禁用RIP相对寻址。地址大小前缀的作用是将计算的有效地址截断并将其零扩展为32位。
这表明在相对寻址模式下,将disp32符号扩展到64位,再添加到RIP,然后截断并进行零扩展。但是,我不确定同一规则是否适用于绝对寻址模式,MOV moffs操作就是这种情况。
从A)FFFFFFFFFFFFFFFF或B)00000000FFFFFFFF将EAX加载到哪个地址?