在字节存储单元中查找位的地址

时间:2019-08-06 03:46:03

标签: byte cpu-architecture memory-address

我在0x31011有一个存储位置,可以存储16个1位符号的数据。这些符号中的每一个都有一个不同的起始位,用于存储其信息:

第一个符号:0x31011->从第0位开始的位
第二个符号:0x31011->起始位从位1开始
第3个符号:0x31011->从第2位开始的位
...
第14个符号:0x31011->第13位的起始位
第15个符号:0x31011->第14位的起始位
第16个符号:0x31011->第15位的起始位

0x31011的十六进制到二进制转换是:110001000000010001

如果能做到的话,我很高兴能对我如何获取每个符号的地址的理解有所启发。我的理解是,对于这些符号中的每一个,我都必须使用0x31011的基地址,然后从该位置提取值,然后对AND运算符使用位掩码,然后向右移动。因此,我最初的想法是无法调用基地址的子地址。

例如,如果我想在第0位找到第一个符号的值,则假定0x31011处的值为0000001100110001:

1:检索值为0x31011 -> 0000001100110001
2:应用以下遮罩:C7 --------------> 0000000011000111
-------------------------------------------------- ------------------------------&
3:查找第一个符号的值 0000000000000001

如果我想在第1位找到第二个符号的值,则假定0x31011处的值为00000001100110001:

1:检索值为0x31011 -> 0000001100110001
2:应用以下遮罩:C6 --------------> 0000000011000110
-------------------------------------------------- ------------------------------&
3:查找第二个符号的值 ------> 0000000000000000
4:右移结果>> 1 ----------> 0000000000000000

如果我想在第2位找到第三个符号的值,则假定0x31011处的值为00000001100110001:

1:检索值为0x31011 -> 0000001100110001
2:应用以下遮罩:C6 --------------> 0000000011000110
-------------------------------------------------- ------------------------------&
3:查找第3个符号的值 ------> 0000000000000000
4:右移结果>> 2 ----------> 0000000000000000

....

如果我想在第15位找到第16个符号的值,则假定0x31011处的值为00000001100110001:

1:检索值为0x31011 -> 0000001100110001
2:应用以下遮罩:80C6 -----------> 1000000011000110
-------------------------------------------------- ------------------------------&
3:查找第16个符号的值 ------> 0000000000000000
4:右移结果>> 15 ---------> 0000000000000000

1 个答案:

答案 0 :(得分:1)

通常,存储器只能按字节寻址,而不能按位寻址。要表示单个位的地址,您需要一个常规地址和一个位偏移量。

但是,某些ISA确实具有一些可用于位寻址存储器的容量。 The 8051 microcontroller's bit-addressable memory是一个值得注意的例子。但是位设置/清除/补码和位上分支指令仅在“直接”寻址模式下可用,因此除非使用自修改代码,否则您不能传递位的地址。与字节加载/存储指令一起使用时,地址00-7F为全字节,而与位指令一起使用时,前16个字节的位为地址。


除了ISA特殊功能(例如可以使用位寻址的指令)之外,您遇到软件问题。单个位不能直接寻址。

您只能将其读取为包含它的字节或单词的一部分。

您当然可以将其位置表示为普通字节地址+偏移量。例如,像这样的C函数很容易在任何具有指针寄存器和右移的普通ISA上实现:

bool get_bit(const char *location, int bit_offset) {
    unsigned char tmp = *location;
    return (tmp >> bit_offset) & 1;
}

例如在x86-64上:

    movzx  eax, byte [rdi]      ; load the byte
    bt     eax, esi             ; CF = bit at position ESI
    setc   al                   ; set AL = CF
    ret

在实际地址不需要一个寄存器宽的机器上的机器上,您可以将位地址编码为单个整数值,且位偏移量为低3位。 (对于具有较大字节的计算机,则为更多位)。然后,要使用它,您需要右移以获取实际的机器地址,并屏蔽以提取位偏移量以用作右移计数。