Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在汇编语言中定义双字中存储4个字符?_Assembly_Masm_X86 16 - Fatal编程技术网

Assembly 如何在汇编语言中定义双字中存储4个字符?

Assembly 如何在汇编语言中定义双字中存储4个字符?,assembly,masm,x86-16,Assembly,Masm,X86 16,我目前正在使用MASM对DOSBox进行汇编编程(16位) var1 dd 'abcd' 对于上述代码,MASM正在生成错误: A2010:语法错误 语法有什么问题?我只是在一个双字中存储4个字符 我正在做16位组装,这是个问题吗?我只能使用db和dw,因为其他变量大于16位吗?var1 db'abcd'(而不是dd)将所需的4个字节按源代码顺序放入内存 使用db以外的变量的目的是什么 编写初始值设定项的方便性,dd1234h比db34h,12h,0,0更方便,但将相同的数据汇编到输出文件中。

我目前正在使用MASM对DOSBox进行汇编编程(16位)

var1 dd 'abcd'
对于上述代码,MASM正在生成错误:

A2010:语法错误

语法有什么问题?我只是在一个双字中存储4个字符


我正在做16位组装,这是个问题吗?我只能使用
db
dw
,因为其他变量大于16位吗?

var1 db'abcd'
(而不是
dd
)将所需的4个字节按源代码顺序放入内存

使用db以外的变量的目的是什么

编写初始值设定项的方便性,
dd1234h
db34h,12h,0,0
更方便,但将相同的数据汇编到输出文件中。此外,MASM在使用符号时将其视为隐含操作数大小

MASM的更高版本确实接受
dd'abcd'
,但它们会终止它。(而不是像NASM那样以源代码顺序将字节组装到内存中。)请参阅

NASM将接受
mov eax,'abcd'
dd'abcd'
很好:多字符文字只是整数文字的另一种形式,第一个字节在内存中排在第一位(最低有效),因为x86是小尾端。i、 在NASM中,多字符整数文字的内存顺序与其源顺序相匹配

但是当与
dd
dw
一起使用时,MASM会反转它们,因此第一个字符成为整数的最高有效字节,内存顺序与源顺序相反。即使在支持该语法并使用十六进制ASCII码加注释的MASM版本中,也最好避免这种情况


在MASM中,
var1 dd
vs.
db
还设置了访问数据的默认操作数大小(如果将其声明为变量而不是标签)

使用
var1 db…
意味着您必须在任何时候使用
mov eax、[var1]
访问所有4个字节时使用显式
dword ptr
。如果没有dword ptr[var1],MASM将抱怨操作数大小不匹配

但是,如果您将它声明为一个普通标签,而不是绑定到将字节组装到内存中的任何db或dd指令,那么我认为您可以自由地使用任意大小的标签

(更新:显然,带有
的标签在MASM代码部分之外是一个错误。我不确定是否有方法仅声明一个不是MASM“变量”的数据标签。请参阅注释中的讨论。)


请注意,在MASM语法中,
mov eax,var1
相当于
mov eax,[var1]
,但我更喜欢使用
[]

明确内存引用,因为您正在存储4个字节,所以请尝试
var1 db'abcd'
。在内存中也是一样的。我知道这一点,但我应该知道如何使用dd,或者使用db以外的变量的目的是什么?早期版本的MASM和TASM不支持将字符串放在
db
以外的类型中的语法。某些汇编器的更高版本(以及其他兼容产品,如wasm和jwasm)确实支持您所做的工作。这很重要。即使对于支持它的汇编器,当在内存中查看大于单个字节(dw、dd、dq等)并加载字符数组的类型时,它们的顺序也会相反(因为x86是小端处理器)。因此,如果这确实起作用,当在内存中查看时,字节将显示为
d
c
b
a
。您可能希望查看我的注释。MASM是否支持这一点取决于产品的使用年限。旧版本的MASM不支持它,但新版本支持它(不确定更改的截止点在哪里)@MichaelPetch:谢谢,是的,已经在更新:)如果我有这个权利,在NASM的MASM=
'dcba'
中,因为支持多字符整数文字的MASM版本在内存中的顺序与其源代码顺序相反?我可以在最新版本的MASM上确认,
dd'abcd'
输出这些字节(这是一个32位程序的反汇编):
00DB85D4 64 63 62 arpl word ptr fs:[edx+61h],sp
。所以MASM实际上是以相反的方式输出它们。JWASM和WASM(WASM=watcom assembler)也是如此。这可能会让您感到惊讶,但在数据段中,一行上带有冒号(
label1:
)的标签本身就是一个错误。实际上,标签上唯一应该显示冒号的地方是在代码段中。经验法则是,在非代码部分的标签后面使用冒号基本上是错误的。这是旧编译器(TASM/MASM)的经验法则。这种行为在后来的版本lol中发生了变化。但如果有人使用旧的TASM/MASM,我不会依赖它来进行无错误的实际组装。如果您想让它在不同版本的汇编器上工作,它应该是
label1 db'abcd'
(不带
label1
(不带冒号)如果您支持不同版本的汇编器,那么它本身就不正确。实际上,归根结底就是这个问题。在非代码段中定义数据的最兼容方式是永远不要使用
,标签(不带冒号)必须始终位于声明数据的行上。
;; I'm not sure this is correct, I'm making this up from memory
;; and I've never actually used MASM.  I know the syntax from SO answers.
.data
    label1:         ; "Just" a label, no data
      db 'abcd'       

    ; little-endian 'abcd'
    var2  dd 64636261h        ; no : so the symbol becomes a variable with a size from the dd

.code
func:
    mov  eax, [label1]                ; legal I think
    mov  al, [label1]                 ; also legal
    mov  eax, dword ptr [label1]      ; always works
    movzx  eax,  byte ptr [label1+2]  ; zero extend the 'c' into EAX

    inc  [label1]                  ; ERROR: ambiguous operand-size

    mov  eax, [var1]               ; fine, both operands are dwords
    mov  al, [var1]                ; ERROR: operand-size mismatch
    mov  al, byte ptr [var1]       ; load the low byte of the dword

    inc  [var1]                   ; legal: the "variable" implies dword operand size
    inc  dword ptr [var1]         ; same as above
    and  byte ptr [var1], ~20h    ; upper-case just the first character, 'abcd' into 'Abcd'