繁体   English   中英

装配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 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本身上的特殊内存小块,无法通过上述数字地址来寻址,而只能通过包含寄存器数的指令操作码来寻址(在源代码中它们的名称为axbx ,... )。

这意味着您的问题中没有寄存器,谈论其中的寄存器是没有意义的。

在普通的汇编器中,[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

请注意, ABD只是在内存中标记一些地址的标签,这就是大多数汇编器如何使用符号的方式。 在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-10D:算起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个字节中,即B0D (D + 0)之后的零字节。 查看我的“已编译”内存,并在那里计算字节数以适应偏移量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM