汇编 x86 MASM 中的十六进制数组
Array in Hexadecimal in Assembly x86 MASM
如果:
(我相信寄存器彼此相邻......)
A BYTE 0xB, 0d20, 0d10, 0d13, 0x0C
B WORD 0d30, 0d40, 0d70, 0hB
D DWORD 0xB0, 0x200, 0x310, 0x400, 0x500, 0x600
然后:
- 什么是[A+2]?答案是 0d20 或 0x15
- 什么是[B+2]?答案是 40 或 0x28
- 什么是[D+4]?不确定
- 什么是[D-10]?不确定
我认为这些就是答案,但我不确定。由于一个 WORD 是 1 个字节,而 DWORD 是 2 个字,因此当您计算 [B+2] 的数组时,您应该从 0d30 开始,然后是 0d40(计算两个字)。 [A+2] 是 0d20 因为你在计算两个字节。我究竟做错了什么?请帮忙。谢谢
编辑
是不是因为:考虑到 A、B 和 D 的第一个值是偏移量 x86 是小端...A = 0d10,从那里再算 2 B...字节(十进制) ) = 30,0,40,0,70,0,11,0 B 是 0d40,从 D 中算出 2 个字节...字节(十六进制)= 0x200, 0,0,0,...0, 2,0,0,...0x10,3,0,0,...0,4,0,0,...0,5,0,0,...0,6, 0, 0 D 是 0x200。从那里数 4 个字节。从 0xb0 向后数 10 个字节。那么 [D-10] 不等于 0x0C 吗?谢谢
另外如果我做[B-3],会是0d13吗?有人告诉我它实际上在 0d10 和 0d13 之间,因此它将是 0A0D,并且由于小端字节序将是 0D0A。那是对的吗?谢谢!!
编辑
WORD 是 2 个 BYTE。 DWORD 是两个 WORD("D" 代表 "double")。 QWORD 是 4*WORD (Quad).
内存 以字节为单位寻址,即。内存内容可以看作(对于三个字节,其值为:0xB、20、10):
address | value
----------------
0000 | 0B
0001 | 14
0002 | 0A
WORD 在内存中占用两个字节,在 x86 上,最低有效字节在低地址,最高有效字节在高地址。
所以 WORD 0x1234 存储在地址 0xDEAD 的内存中为:
address | value
----------------
DEAD | 34
DEAE | 12
x86 上的寄存器是直接位于 CPU 本身的特殊微小内存位,无法通过上述数字地址寻址,只能通过包含寄存器编号的指令操作码(在源代码中被命名为 ax
, bx
, ...).
这意味着你的问题中没有寄存器,在其中谈论寄存器是没有意义的。
在普通汇编器中 [B+2] 将是 BYTE 40,(B 处的字节是:30、0、40、0、70、0、11、0)。在 MASM 中,它可能有所不同,因为它试图与 "variables" 一起工作,同时考虑它们的大小,因此 [B+2] 可能被视为 WORD 70。我不确定,我不想要知道,MASM 有太多的怪癖,无法按逻辑使用,你必须学习它们。 (只需使用 B WORD 0, 1, 2, 3, 4
MOV ax,[B+2]
创建短代码并检查调试器中的反汇编)。
[A+2] 是 10。您忽略了 [A] 是 [A+0] 的要点。就像在 C/C++ 数组中一样,索引从 0 开始,而不是从 1 开始。
如果您在纸上绘制字节(例如 DWORD 0x310
编译为 10 03 00 00
六字节),则可以轻松找出其余答案。
我想知道你在第一个可能的答案中得到 0x15 的位置,因为我在 A
中没有看到任何值 21。
根据新评论进行编辑...我会 "compile" 为您完成,确保您理解每个字节,或者在回答下询问哪个字节不清楚。
; A BYTE 0xB, 0d20, 0d10, 0d13, 0x0C
A:
0B 14 0A 0D 0C
; B WORD 0d30, 0d40, 0d70, 0hB
B: ;▼ ▼ ▼ ▼
1E 00 28 00 46 00 0B 00
; D DWORD 0xB0, 0x200, 0x310, 0x400, 0x500, 0x600
D: ;▼ ▼ ▼ ▼ ▼ ▼
B0 00 00 00 00 02 00 00 10 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00
请注意 A
、B
和 D
只是标记内存中某个地址的标签,这就是大多数汇编程序使用符号的方式。在 MASM 中它更棘手,因为它试图成为 "clever" 并且不仅保留地址,而且它知道 D
被定义为 DWORD 而不是 BYTE。不同的汇编程序不是这种情况。
现在 MASM 中的 [D+4]
是棘手的,它可能会使用大小知识来默认该表达式的 DWORD 大小(在其他汇编器中你应该指定,比如 "DWORD PTR [D+4]",或者它被推导如果可能,自动从目标寄存器大小)。所以 [D+4] 将获取字节 00 02 00 00
= DWORD 00000200
。 (我只希望 MASM 也不要将 +4 偏移量重新计算为 +4 个双字,即以字节为单位的 +16)。
现在针对您的评论,我会将它们撕成小块并带有错误,因为虽然通常很容易理解您的意思,但在 Assembly 中,一旦您开始编写代码,仅仅有良好的意图是不够的,您一定要准确无误,CPU不会填空,照你写的做。
Can you explain how did you get 0d13 of A and through to 0d30 of B @Jester?
转到我的 "compiled" 字节,D-1(当偏移量以字节为单位时)表示从 D:
地址返回一个字节,即。 B 行末尾的 00
。现在 D-10
从 D:
算回 10 个字节...这将转到 A
行中的 0D
,因为 B
数组中有 8 个字节,并且剩下的两个在 A
数组的末尾。
现在,如果您从该地址读取 4 个字节:0D 0C 1E 00
= DWORD 001E0C0D
。 (Jester 在他的最终 "dword" 值中不小心将小数 13
混成了 13h
)
each value in B will occupy two "slots" as you count back? And each value in A will occupy four "slots"?
反过来,B 中的两个值将构成 1 个 DWORD 槽,A 中的四个值将构成 1 个 DWORD。正如 "D" 6 个 DWORD 的数据也可以被视为 12 个 WORD 值,或 24 个 BYTE 值。例如 DWORD PTR [A+2]
是 1E0C0D0A
.
first value of A,B, and D are offsets x86 is little endian
"value of A" 实际上是一些内存地址,我想在这种情况下我自动不提及 "value",但是 "address"、"pointer" 或 "label"(虽然"value of symbol A"是有效的英文句子,符号分配地址后可以解析)。
OFFSET A
在 MASM 中具有特殊的特殊含义,从它的段开始获取地址 A
的字节偏移量(在 32b 模式下,这通常是人类的 "address",因为段从 0 开始,内存是平面映射的。在实模式下,地址的段部分很重要,因为偏移量只有 16 位(只能通过偏移量寻址 64k 内存)。
在你的情况下,我会说 "value at A",如 "content of memory at address A"。这很微妙,我知道,但是当每个人都这样说话时,就很清楚了。
B is 0d40
[B+2]
是 40
。 B+2
是某个地址+2。 B
是一些地址。这是标记 "value from memory at x".
的 [x]
括号
虽然在 MASM 中有点不同,它会将 mov eax,D
编译为 mov eax,DWORD PTR [D]
以模仿 "variable" 用法,但这是 MASM 的特定怪癖。避免使用该语法,它隐藏了未聚焦 reader 源的内存使用情况,即使在 MASM 中也使用 mov eax,[D]
(或者理想地摆脱 MASM)。
D...bytes (in hex) = 0x200, 0,0,0,...
0x200
不是字节,十六进制格式具有整洁的特征,即两个数字对形成单个字节。所以 hexa 200
是 3 位数字 => 一个半字节。
考虑这些 DWORD 值是如何从字节创建的。在十进制格式中,您将不得不重新计算整个值,因此字节 40、30、20、10 是 40 + 30*256 + 20*65536 + 10* 16777216 = 169090600 -> 原始值在那里不可见。使用 hexa 28 1E 14 0A
,您只需按正确的顺序重新组装它们 0A141E28
.
D is 0x200.
不是,D
是地址。甚至 [D]
也是 0xB0
.
Count 10 bytes backwards from 0xb0. So wouldn't [D-10] be equal to 0x0C?
B0
位于 D+0 地址。您不将其计入 [D-10] 中的那 10 个字节,即 B0
是超出 D
(D+0) 的零字节。查看我的 "compiled" 内存并计算那里的字节数以熟悉偏移量。
如果: (我相信寄存器彼此相邻......)
A BYTE 0xB, 0d20, 0d10, 0d13, 0x0C
B WORD 0d30, 0d40, 0d70, 0hB
D DWORD 0xB0, 0x200, 0x310, 0x400, 0x500, 0x600
然后:
- 什么是[A+2]?答案是 0d20 或 0x15
- 什么是[B+2]?答案是 40 或 0x28
- 什么是[D+4]?不确定
- 什么是[D-10]?不确定
我认为这些就是答案,但我不确定。由于一个 WORD 是 1 个字节,而 DWORD 是 2 个字,因此当您计算 [B+2] 的数组时,您应该从 0d30 开始,然后是 0d40(计算两个字)。 [A+2] 是 0d20 因为你在计算两个字节。我究竟做错了什么?请帮忙。谢谢
编辑
是不是因为:考虑到 A、B 和 D 的第一个值是偏移量 x86 是小端...A = 0d10,从那里再算 2 B...字节(十进制) ) = 30,0,40,0,70,0,11,0 B 是 0d40,从 D 中算出 2 个字节...字节(十六进制)= 0x200, 0,0,0,...0, 2,0,0,...0x10,3,0,0,...0,4,0,0,...0,5,0,0,...0,6, 0, 0 D 是 0x200。从那里数 4 个字节。从 0xb0 向后数 10 个字节。那么 [D-10] 不等于 0x0C 吗?谢谢
另外如果我做[B-3],会是0d13吗?有人告诉我它实际上在 0d10 和 0d13 之间,因此它将是 0A0D,并且由于小端字节序将是 0D0A。那是对的吗?谢谢!! 编辑
WORD 是 2 个 BYTE。 DWORD 是两个 WORD("D" 代表 "double")。 QWORD 是 4*WORD (Quad).
内存 以字节为单位寻址,即。内存内容可以看作(对于三个字节,其值为:0xB、20、10):
address | value
----------------
0000 | 0B
0001 | 14
0002 | 0A
WORD 在内存中占用两个字节,在 x86 上,最低有效字节在低地址,最高有效字节在高地址。
所以 WORD 0x1234 存储在地址 0xDEAD 的内存中为:
address | value
----------------
DEAD | 34
DEAE | 12
x86 上的寄存器是直接位于 CPU 本身的特殊微小内存位,无法通过上述数字地址寻址,只能通过包含寄存器编号的指令操作码(在源代码中被命名为 ax
, bx
, ...).
这意味着你的问题中没有寄存器,在其中谈论寄存器是没有意义的。
在普通汇编器中 [B+2] 将是 BYTE 40,(B 处的字节是:30、0、40、0、70、0、11、0)。在 MASM 中,它可能有所不同,因为它试图与 "variables" 一起工作,同时考虑它们的大小,因此 [B+2] 可能被视为 WORD 70。我不确定,我不想要知道,MASM 有太多的怪癖,无法按逻辑使用,你必须学习它们。 (只需使用 B WORD 0, 1, 2, 3, 4
MOV ax,[B+2]
创建短代码并检查调试器中的反汇编)。
[A+2] 是 10。您忽略了 [A] 是 [A+0] 的要点。就像在 C/C++ 数组中一样,索引从 0 开始,而不是从 1 开始。
如果您在纸上绘制字节(例如 DWORD 0x310
编译为 10 03 00 00
六字节),则可以轻松找出其余答案。
我想知道你在第一个可能的答案中得到 0x15 的位置,因为我在 A
中没有看到任何值 21。
根据新评论进行编辑...我会 "compile" 为您完成,确保您理解每个字节,或者在回答下询问哪个字节不清楚。
; A BYTE 0xB, 0d20, 0d10, 0d13, 0x0C
A:
0B 14 0A 0D 0C
; B WORD 0d30, 0d40, 0d70, 0hB
B: ;▼ ▼ ▼ ▼
1E 00 28 00 46 00 0B 00
; D DWORD 0xB0, 0x200, 0x310, 0x400, 0x500, 0x600
D: ;▼ ▼ ▼ ▼ ▼ ▼
B0 00 00 00 00 02 00 00 10 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00
请注意 A
、B
和 D
只是标记内存中某个地址的标签,这就是大多数汇编程序使用符号的方式。在 MASM 中它更棘手,因为它试图成为 "clever" 并且不仅保留地址,而且它知道 D
被定义为 DWORD 而不是 BYTE。不同的汇编程序不是这种情况。
现在 MASM 中的 [D+4]
是棘手的,它可能会使用大小知识来默认该表达式的 DWORD 大小(在其他汇编器中你应该指定,比如 "DWORD PTR [D+4]",或者它被推导如果可能,自动从目标寄存器大小)。所以 [D+4] 将获取字节 00 02 00 00
= DWORD 00000200
。 (我只希望 MASM 也不要将 +4 偏移量重新计算为 +4 个双字,即以字节为单位的 +16)。
现在针对您的评论,我会将它们撕成小块并带有错误,因为虽然通常很容易理解您的意思,但在 Assembly 中,一旦您开始编写代码,仅仅有良好的意图是不够的,您一定要准确无误,CPU不会填空,照你写的做。
Can you explain how did you get 0d13 of A and through to 0d30 of B @Jester?
转到我的 "compiled" 字节,D-1(当偏移量以字节为单位时)表示从 D:
地址返回一个字节,即。 B 行末尾的 00
。现在 D-10
从 D:
算回 10 个字节...这将转到 A
行中的 0D
,因为 B
数组中有 8 个字节,并且剩下的两个在 A
数组的末尾。
现在,如果您从该地址读取 4 个字节:0D 0C 1E 00
= DWORD 001E0C0D
。 (Jester 在他的最终 "dword" 值中不小心将小数 13
混成了 13h
)
each value in B will occupy two "slots" as you count back? And each value in A will occupy four "slots"?
反过来,B 中的两个值将构成 1 个 DWORD 槽,A 中的四个值将构成 1 个 DWORD。正如 "D" 6 个 DWORD 的数据也可以被视为 12 个 WORD 值,或 24 个 BYTE 值。例如 DWORD PTR [A+2]
是 1E0C0D0A
.
first value of A,B, and D are offsets x86 is little endian
"value of A" 实际上是一些内存地址,我想在这种情况下我自动不提及 "value",但是 "address"、"pointer" 或 "label"(虽然"value of symbol A"是有效的英文句子,符号分配地址后可以解析)。
OFFSET A
在 MASM 中具有特殊的特殊含义,从它的段开始获取地址 A
的字节偏移量(在 32b 模式下,这通常是人类的 "address",因为段从 0 开始,内存是平面映射的。在实模式下,地址的段部分很重要,因为偏移量只有 16 位(只能通过偏移量寻址 64k 内存)。
在你的情况下,我会说 "value at A",如 "content of memory at address A"。这很微妙,我知道,但是当每个人都这样说话时,就很清楚了。
B is 0d40
[B+2]
是 40
。 B+2
是某个地址+2。 B
是一些地址。这是标记 "value from memory at x".
[x]
括号
虽然在 MASM 中有点不同,它会将 mov eax,D
编译为 mov eax,DWORD PTR [D]
以模仿 "variable" 用法,但这是 MASM 的特定怪癖。避免使用该语法,它隐藏了未聚焦 reader 源的内存使用情况,即使在 MASM 中也使用 mov eax,[D]
(或者理想地摆脱 MASM)。
D...bytes (in hex) = 0x200, 0,0,0,...
0x200
不是字节,十六进制格式具有整洁的特征,即两个数字对形成单个字节。所以 hexa 200
是 3 位数字 => 一个半字节。
考虑这些 DWORD 值是如何从字节创建的。在十进制格式中,您将不得不重新计算整个值,因此字节 40、30、20、10 是 40 + 30*256 + 20*65536 + 10* 16777216 = 169090600 -> 原始值在那里不可见。使用 hexa 28 1E 14 0A
,您只需按正确的顺序重新组装它们 0A141E28
.
D is 0x200.
不是,D
是地址。甚至 [D]
也是 0xB0
.
Count 10 bytes backwards from 0xb0. So wouldn't [D-10] be equal to 0x0C?
B0
位于 D+0 地址。您不将其计入 [D-10] 中的那 10 个字节,即 B0
是超出 D
(D+0) 的零字节。查看我的 "compiled" 内存并计算那里的字节数以熟悉偏移量。