[英]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
然后:
我认为这些是答案,但我不确定。 由于WORD为1 BYTE,AND DWORD为2 WORDS,因此,例如,当计算[B + 2]的数组时,应从0d30开始,然后从0d40开始(计算两个WORD)。 [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个字节。 DWORD是两个WORD(“ D”代表“ double”)。 QWORD是4 * WORD(四倍)。
内存以字节为单位,即。 内存的内容可以视为(对于三个字节,其值分别为: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中,它可能有所不同,因为它在尝试同时考虑“变量”的大小时也是如此,因此[B + 2]可能被视为WORD70。我不确定,我也不想知道,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。
由于有新注释而进行编辑...我将为您“编译”它,确保您了解每个字节,或在回答时询问不清楚哪个字节。
; 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中,它更加棘手,因为它试图变得“聪明”,不仅保留地址,而且知道D
被定义为DWORD而不是BYTE。 不同的汇编器不是这种情况。
现在,MASM中的[D+4]
很棘手,它可能会使用大小知识来默认将该表达式的DWORD大小设置为默认值(在其他汇编程序中,您应指定“ DWORD PTR [D + 4]”,或从尽可能自动达到目标寄存器的大小)。 因此[D + 4]将获取字节00 02 00 00
= DWORD 00000200
。 (我只是希望MASM也不要将+4偏移也重新计算为+4 dword,即+16字节)。
现在对您的评论,我将它们错误地撕成碎片,因为通常很容易理解您的意思,在汇编中,一旦您开始编写代码,仅仅具有良好的意图是不够的,您必须准确无误,CPU将不会填补任何空白,并完全按照您的编写来做。
您能解释一下如何获得A的0d13以及B @Jester的B的0d30吗?
转到我的“已编译”字节,D-1(偏移量以字节为单位)表示从D:
地址返回一个字节,即。 B行末的那个00
。 现在对于D-10
从D:
算起10个字节D:
...这将在A
行中到达0D
,因为8个字节在B
数组中,其余两个在A
数组的末尾。
现在,如果您从该地址读取4个字节: 0D 0C 1E 00
= DWORD 001E0C0D
。 (Jester在其最终的“ dword”值中无意间将十进制13
混合为13h
)
当您算回来时,B中的每个值都将占据两个“槽”? 并且A中的每个值都将占据四个“槽”?
换句话说,B中的两个值将形成1个DWORD插槽,A中的四个值将形成1个DWORD插槽。 正如6个DWORD的“ D”数据也可以视为12个WORD值或24个BYTE值一样。 例如, DWORD PTR [A+2]
是1E0C0D0A
。
A,B和D的第一个值是偏移量x86是小端
“ A的值”实际上是一些内存地址,我想在这种情况下我不会自动提及“值”,但是“地址”,“指针”或“标签”(尽管“ A的值”是有效的英语句子) ,并且可以在符号分配了地址后解析)。
OFFSET A
在MASM中具有特殊的含义,自段A
的开头开始取地址A
的字节偏移量(在32b模式下,这通常是人类的“地址”,因为段从0开始并且内存是平面映射的。)模式的地址部分非常重要,因为偏移量只有16位(只有64k的内存只能通过偏移量寻址)。
在您的情况下,我会说“ A 处的值”,即“地址A处的内存内容”。 我知道这很微妙,但是当每个人都这样讲话时,很明显。
B是0d40
[B+2]
是40
。 B+2
是某个地址+2。 B
是一些地址。 它是[x]
括号,标记“来自x的内存值”。
尽管在MASM中有所不同,但是它将编译mov eax,D
作为mov eax,DWORD PTR [D]
来模仿“可变”用法,但这是MASM的特殊功能。 避免使用该语法,即使在MASM中,它也会从源头不集中的读者那里隐藏内存使用情况,甚至使用mov eax,[D]
(或理想地摆脱MASM)。
D ...字节(十六进制)= 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是0x200。
不, D
是地址。 甚至[D]
都是0xB0
。
从0xb0向后计数10个字节。 所以[D-10]等于0x0C吗?
B0
位于D + 0地址。 您无需将其计入[D-10]的那10个字节中,即B0
是D
(D + 0)之后的零字节。 查看我的“已编译”内存,并在那里计算字节数以适应偏移量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.