在 32 位 MASM 中声明变量的技术机制和操作是什么?
What are the technical mechanics and operation of declaring variables in 32-bit MASM?
使用32位MASM程序集和MASM version 11 SDK,我在编译过程中发现了一个错误。该错误指向我声明一个双字 (dd) 大小的变量的行。该消息说该变量对于我尝试分配给它的字符串来说太小了。当我将变量定义为字节而不是 (db) 时,程序编译时没有错误。这意味着用 db 指令声明一个变量比声明一个双数据大小允许更多的存储。下面是错误信息指向的双字变量的声明代码:
.data
msg_run dd "Ran a function.", 0
我把msg_run的数据大小改成了一个字节:
.data
msg_run db "Ran a function.", 0
当我尝试用第二行编译时,程序编译 运行 没有问题。为什么错误暗示声明为字节大小的变量比声明为双字大小的变量具有更大的容量?尾随的“,0”有什么作用吗?
我查看的来源:
https://www.cs.virginia.edu/~evans/cs216/guides/x86.html
https://www.shsu.edu/~csc_tjm/fall2003/cs272/intro_to_asm.html
严格的数据定义语法要求程序员编写以逗号分隔的每个元素会使声明字符串变得乏味:
myString db 'M', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g', 0
所以 MASM(和所有其他主流汇编程序)放宽了
中的语法
myString db "My string", 0
注意 我用引号 '
表示字符(即数字),用双引号 "
表示字符串,我不知道确切的语法由 MASM 使用,它可能会将 1 个字符的字符串转换为 char。
您在 dd
案例中看到的内容看起来与上面的 shorthand 非常相似,但它不是声明字符串的语法,实际上,它创建 numbers。
当在需要数字的地方使用像 "ABCD" 这样的字符串时(比如在 dd
中或作为立即数),MASM 会将其转换为 0x44434241
。这些是字符D、C、B、A的值。
完成反转是因为语法主要用于指令立即数,例如 mov eax, "ABCD"
或 cmp eax, "ABCD"
.
这样,由于 x86 字节顺序,将 eax
存储到内存将创建字符串 "ABCD"(以正确的顺序)。
这也适用于检查表的签名,因为这些签名旨在在内存中正确拼写,但当然,一旦加载到寄存器中就会反转。
在 NASM 中,您甚至可以用 mov eax, ("ABCD" + "EFGH") / 2
之类的东西激怒所有人,强化了将这些字符串视为数字的观点。这也适用于 MASM。
我不记得我用过 myVar dd "ABCD"
的情况,但当结构具有在内存中拼写为 reversed 的固定字符串时,它可能很有用.
:
MASM treats strings (things between the quotes) in a special way when you use db
. db
is a single character (byte) so MASM will take each character and store it in a byte. This type of processing doesn't occur the same way with types larger than a byte ( dw
and dd
). In those situations MASM tries to stuff your string into into a single DWORD (32-bit value). Look what happens if you use dd
and make your string <=4 characters in length. The error should disappear but the characters are placed in memory in reverse order.
使用32位MASM程序集和MASM version 11 SDK,我在编译过程中发现了一个错误。该错误指向我声明一个双字 (dd) 大小的变量的行。该消息说该变量对于我尝试分配给它的字符串来说太小了。当我将变量定义为字节而不是 (db) 时,程序编译时没有错误。这意味着用 db 指令声明一个变量比声明一个双数据大小允许更多的存储。下面是错误信息指向的双字变量的声明代码:
.data
msg_run dd "Ran a function.", 0
我把msg_run的数据大小改成了一个字节:
.data
msg_run db "Ran a function.", 0
当我尝试用第二行编译时,程序编译 运行 没有问题。为什么错误暗示声明为字节大小的变量比声明为双字大小的变量具有更大的容量?尾随的“,0”有什么作用吗?
我查看的来源:
https://www.cs.virginia.edu/~evans/cs216/guides/x86.html https://www.shsu.edu/~csc_tjm/fall2003/cs272/intro_to_asm.html
严格的数据定义语法要求程序员编写以逗号分隔的每个元素会使声明字符串变得乏味:
myString db 'M', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g', 0
所以 MASM(和所有其他主流汇编程序)放宽了
中的语法myString db "My string", 0
注意 我用引号 '
表示字符(即数字),用双引号 "
表示字符串,我不知道确切的语法由 MASM 使用,它可能会将 1 个字符的字符串转换为 char。
您在 dd
案例中看到的内容看起来与上面的 shorthand 非常相似,但它不是声明字符串的语法,实际上,它创建 numbers。
当在需要数字的地方使用像 "ABCD" 这样的字符串时(比如在 dd
中或作为立即数),MASM 会将其转换为 0x44434241
。这些是字符D、C、B、A的值。
完成反转是因为语法主要用于指令立即数,例如 mov eax, "ABCD"
或 cmp eax, "ABCD"
.
这样,由于 x86 字节顺序,将 eax
存储到内存将创建字符串 "ABCD"(以正确的顺序)。
这也适用于检查表的签名,因为这些签名旨在在内存中正确拼写,但当然,一旦加载到寄存器中就会反转。
在 NASM 中,您甚至可以用 mov eax, ("ABCD" + "EFGH") / 2
之类的东西激怒所有人,强化了将这些字符串视为数字的观点。这也适用于 MASM。
我不记得我用过 myVar dd "ABCD"
的情况,但当结构具有在内存中拼写为 reversed 的固定字符串时,它可能很有用.
MASM treats strings (things between the quotes) in a special way when you use
db
.db
is a single character (byte) so MASM will take each character and store it in a byte. This type of processing doesn't occur the same way with types larger than a byte (dw
anddd
). In those situations MASM tries to stuff your string into into a single DWORD (32-bit value). Look what happens if you usedd
and make your string <=4 characters in length. The error should disappear but the characters are placed in memory in reverse order.