最近,我正在编写程序集,并且我编写的程序在DOSBox下运行没有任何问题。现在,我需要使用DOS将同一程序移植到实际计算机中,但是会出现一些问题。
首先,在DOSBox下,我正在使用ML进行编译,但是在真正的PC上,一旦输入ML,它就会说:
该程序不能在DOS模式下运行。
因此,我一直在寻找一种解决方案,并发现MASM可以毫无问题地编译asm程序。不幸的是,我需要移植的程序在编译时报告严重错误(仅1种类型)。
错误A2061:段寄存器使用不当
出现这些问题的路线如下
... CARLOC EQU $-2 ... MOV [WORD PTR DS:CARLOC],DX ...
以下代码也会出现相同的问题
... MOV ES,CX MOV AL, [BYTE PTR ES:0017H] ...
到目前为止,我已经尝试将BYTE PTR [ES:0017H]
产生相同错误的BYTE PTR更改为
并BYTE PTR ES:0017H
成功地在
其中编译了代码,该程序运行了但无法正常运行
注意:我不知道当前在哪种架构下工作。可能无法物理访问该计算机,但是如果我可以键入一些代码来查看屏幕上的信息,我将很高兴这样做。
代码在这里,如果我需要在这里粘贴它就太长了,然后确定,但是直到那时https://pastecode.xyz/view/5f332efc
PC说它运行MSDOS 6
(更新:Michael Petch说一些与 MASM或MASM兼容的汇编器允许在括号内使用大小和段覆盖。但是update2:并非全部,因此这实际上可能是问题所在。至少是标准样式,因此我建议始终这样做)
使用所需的常规MASM语法MOV [CARLOC], DX
。 根据您声明的方式carloc
,您可能仍然需要mov word ptr [CARLOC], dx
,但是DS:
已经是默认段。
如果您想对此进行明确说明,MOV word ptr ds:[CARLOC], dx
但我建议在asm源代码中省略冗余DS前缀,因为某些汇编程序的机器代码中包括冗余DS前缀!DS:唯一不是唯一的时间是当与,ds:[bp]
或ebp或一起使用时ds:[esp]
,这暗示SS是默认段。
对于MASM,ds:
还需要数字绝对地址作为前缀。否则,将其视为立即目的地(不考虑方括号),而该目的地当然不是目的地。使用这样的定义CARLOC equ $-2
,您将需要ds:[CARLOC]
。显然,MASM不会ds
在机器代码中添加无用的前缀,因此您不必担心该汇编程序。
如果需要CS / DS / ES / FS / GS / SS前缀,则标准语法是将其放在方括号之外:
MOV AL, ES:[0017H]
AL目的地表示byte ptr
操作数大小,该大小也超出了括号。例如,查看反汇编程序输出。
并
BYTE PTR ES:0017H
成功地将代码编译到其中,
是的,这是有效的语法:方括号在某些情况下是可选的(包括绝对地址或符号)。许多人建议始终在存储操作数周围使用括号(而不是OFFSET symbol
立即数),以使读者更容易理解。
如果您要使用方括号,它们会在size ptr
和seg:
替代之后。
该程序已运行但无法正常运行
然后,您的代码中除了语法错误之外,还有其他错误。
或者,如果您尝试将其构建为Windows可执行文件:当然,将为DOS编写的代码(实模式,在整个计算机的控制下)并以32位或64位构建为代码是行不通的Windows可执行文件(保护模式或64位模式,在操作系统下为Ring 3)。系统调用ABI甚至API也完全不同:它们是不同的操作系统,而DOS API对Windows可执行文件不可用。
Michael还建议,USE32或其他指令可能会使MASM试图将您从自己身上救出来,并拒绝在应该与平面内存模型一起运行的代码中使用分段。但是,如果es:[17H]
可行,那可能不是。