两个十六进制内存地址之间区域中的字节

Posted

技术标签:

【中文标题】两个十六进制内存地址之间区域中的字节【英文标题】:Bytes in area between two hex memory addresses 【发布时间】:2021-04-08 08:13:06 【问题描述】:

我目前正在阅读一本关于 Mainframe Assembly(System Z 的汇编语言编程)的书

在第一章中,我遇到了以下问题:

3.1.1.(2)+ 为数据保留的内存区域从地址 X'2EC9' 开始,以地址 X'30A6' 结束(包括开始和结束) 字节!)。该区域有多少个字节,有多少个半字, 字,双字可以存储在该区域吗?

我明白它们的意思,但我不确定如何找出这些十六进制地址之间的字节数。

【问题讨论】:

123 到 456(含)之间有多少个数字?十六进制而不是十进制只是一种不同的数字书写方式。 所以我们在它们之间有 333 个数字,每个地址包含 1 个字节?这意味着它们之间有 333 个字节? 请注意,Windows 中的计算器具有“程序员”模式,您可以在其中编写和查看 4 种不同基数的数字。如果您不在 Windows 上,可能有其他操作系统具有类似功能的应用程序。 1 到 5 之间有多少个数字? 5-1 还是 5-1+1 还是其他? 【参考方案1】:

计算机内存以字节为单位,(通常)从零开始编号。您可以用十进制计数,或者更常见的是用十六进制计数。处理器指令对单个字节和多个字节进行操作。字节数可以是固定数字,也可以是可变数字。

术语 HalfwordFullwordDoublewordQuadword 是固定数量的字节单元的术语,并且取决于术语 word 的定义。一个字节可能包含 2、4 或 8 个连续的内存字节。

IBM z/Architecture(以及它的前身回到 IBM S/360)中,一个 单词 由 4 个字节组成。 A *Fullword”(下图中的“FW”)与“Word”相同。A Halfword(下图中的“HW”)是半个字,所以是2个字节。A Doubleword(“DW”)是2个字,所以是8个字节。最后,一个Quadword是4个字,所以是16个字节。

请注意,某些处理器指令要求操作数位于半字、全字、双字甚至四字边界上。这意味着最低编号字节的地址或编号必须分别被 2、4、8 或 16 整除。这创造了术语“*半字对齐”、“全字对齐”等。

其他指令对半字、全字等操作数进行操作,无论它们是否对齐。因此,通常这些术语表示特定数量的连续内存字节数。

下图说明了这些术语:

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
| B | B | B | B | B | B | B | B | B | B | B | B | B | B | B | B | B | B |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18   decimal
00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F  10  11  12   hexadecimal

+-------+-------+-------+-------+-------+-------+-------+-------+-------+---
|   HW  |   HW  |   HW  |   HW  |   HW  |   HW  |   HW  |   HW  |   HW  |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+---
00      02      04      06      08      10      12      14      16      18   decimal
00      02      04      06      08      0A      0C      0E      10      12   hexadecimal

+---------------+---------------+---------------+---------------+-----------
|       FW      |       FW      |       FW      |       FW      |       FW
+---------------+---------------+---------------+---------------+-----------
00              04              08              12              16           decimal
00              04              08              0C              10           hexadecimal

+-------------------------------+-------------------------------+-----------
|               DW              |               DW              |        DW
+-------------------------------+-------------------------------+-----------
00                              08                              16           decimal
00                              08                              10           hexadecimal

+---------------------------------------------------------------+-----------
|                               QW                              |        QW
+---------------------------------------------------------------+-----------
00                                                              16           decimal
00                                                              10           hexadecimal

B = 字节,HW = 半字,FW = 全字,DW = 双字,QW = 四字

最后,回到你的问题。第一个字节是字节号 2EC9(以十六进制表示),最后一个字节是字节号 30A6。两个数之差加 1 等于字节数。 30A6 - 2EC9 + 1 = 1DE(十六进制)或 478(十进制)。

如果我们忽略对齐,则有 478 / 2 = 239 个半字、478 / 4 = 119 个全字(剩下 2 个字节)、478 / 8 = 59 个双字(剩下 6 个字节)和 478 / 16 = 29 个四字(还剩 14 个字节)。

另一方面,如果我们坚持对齐,首先,我们需要找到从 2EC9 开始的下一个半字、全字、双字和四字边界。这分别是 2ECA、2ECC、2ED0 和 2ED0。其次,我们需要找到 HW、FW、DW 或 QW 可能开始的最后一个地址,最后一个字节仍低于或等于地址 30A6。分别是 30A4、30A0、3098 和 3090。

结果是 238 个半字(还剩 2 个字节)、118 个全字(还剩 6 个字节)、58 个双字(还剩 14 个字节),最后是 29 个四字(还剩 14 个字节)。

既然你正在学习汇编程序,你最好学习十六进制算术。

【讨论】:

您的回复有错别字,四字是16字节而不是8字节。 如果您考虑对齐(半字、全字、双字...),那么有 238 个可能的半字、119 个全字、59 个双字。这是因为第一个字节不在字对齐边界 (2EC9) 上。 @Hogstrom 感谢您这一次提醒我不要偷懒 :-) 我已经调整了我的答案,希望所有的计算都是正确的。 @phunsoft 懒惰是人类的特征。勤奋是一项团队运动。在这一起。

以上是关于两个十六进制内存地址之间区域中的字节的主要内容,如果未能解决你的问题,请参考以下文章

Golang指针

Java内存模型

汇编语言 第三章 寄存器(内存访问)

计算机中的内存

每日思考记录

C语言 Scanf函数