简体   繁体   English

在32位字存储器中连续读取3个字节

[英]Reading successive 3 bytes in a 32-bit word memory

I have a 32-bit word-addressable memory and my data section can start and end at any byte within the memory. 我有一个32位字可寻址存储器,并且我的数据段可以在存储器中的任何字节处开始和结束。

Lets suppose my data section starts at byte 2 (0 being Lowest byte) of word 0x3. 假设我的数据段从字0x3的字节2(0为最低字节)开始。

Then I have to read data from bytes 2 and 3 of word 0x3 and byte 0 of word 0x4. 然后,我必须从字0x3的字节2和3和字0x4的字节0中读取数据。 After this, I must read byte 1, 2 and 3 of word 0x4 and so on...And stop only when I all 3 bytes as zero OR my data section ends. 之后,我必须读取字0x4的字节1、2和3,依此类推...并且仅当我所有3个字节都为零或我的数据段结束时才停止。 The next section has extensible boundary and it can move into my data section so the ending word or byte is not fixed. 下一部分具有可扩展的边界,可以移入我的数据部分,因此末尾字或字节不固定。

Do you have any suggestion on best possible algorithm to tackle this. 您是否对解决此问题的最佳算法有任何建议? I have come up with a way of creating two masks of total 24 bits which I move across words but that seems overkill and gives me large code. 我想出了一种创建总共24位的两个掩码的方法,这些掩码可以在单词之间移动,但是这似乎有些过分,并且给了我很大的代码。 I'm trying to solve it in minimum possible C instructions. 我正在尝试以最少的C指令来解决它。 Looking forward to your advice. 期待您的建议。

from your statement it implies you can only read 32 bit words at a time, no 16 or 8 bit and that also implies you dont have to think/talk about alignment. 从您的陈述中可以看出,您一次只能读取32位字,而不能读取16位或8位字,这也意味着您不必思考/谈论对齐问题。

Just like the processors that do support byte addressable memory, you can implement it the same way if you have an address 0x1002 and you have some 24 bit item then 就像支持字节可寻址内存的处理器一样,如果地址为0x1002并且有一些24位项,则可以用相同的方式实现它。

0x1002 = 0b0001000000000010 the lower two bits describe the byte in the word the upper bits the word number/address 0b00010000000000 0b10 so word address 0x400 starting with byte 2 (endianness is of course a factor, assuming little). 0x1002 = 0b0001000000000010低位两位描述字中的字节,高位位代表字号/地址0b00010000000000 0b10,因此字地址0x400从字节2开始(字节序当然是一个因素,假设很小)。 you also know that 4 - 0b10 = 2 means there are two bytes left in this word and if you need a third you start at offset 0 in the next word. 您还知道4-0b10 = 2表示该字中还有两个字节,如果需要第三个字节,则从下一个字的偏移量0开始。

so you could do something like this untested code: 因此您可以执行以下未经测试的代码:

unsigned int get24 ( unsigned int x )
{  
    unsigned int ra;
    unsigned int ret;
    unsigned int wa;
    unsigned int shift;
    unsigned int rb;

    ret=0;
    wa=x>>2;
    shift=(x&3)<<3;
    rb=load32(wa);
    for(ra=0;ra<3;ra++)
    {
       ret<<=8;
       ret|=(rb>>shift)&0xFF;
       shift+=8;
       if(shift>=32)
       {
           wa++;
           rb=load32(wa);
           shift=0;
       }
    }
}

you can take the byte based approach in another answer, but you have to make sure the compiler is aware of your word based memory limitations, it cant be allowed to do byte reads (well depends on the architecture), nor unaligned accesses (depends on the architecture). 您可以在另一个答案中采用基于字节的方法,但是必须确保编译器知道基于字的内存限制,不允许进行字节读取(取决于体系结构),也不能进行未对齐的访问(取决于架构)。

You could try table based 您可以尝试基于表

//0x00000000 0x00FFFFFF
//0x00000000 0xFFFFFF00
//0x000000FF 0xFFFF0000
//0x0000FFFF 0xFF000000

unsigned int al[4]={0,0,24,16};
unsigned int ar[4]={0,0,8,8};
unsigned int bl[4]={8,0,16,24};
unsigned int br[4]={8,8,16,24};

unsigned int wa;
unsigned int off;
unsigned int ra;
unsigned int rb;
unsigned int ret;

wa=byte_address>>2;
off=byte_address&3;
rb=load32(wa);
ret=(rb<<bl[off])>>br[off];
//ret=(rb<<bl[off])>>(off<<3);
if(off&2)
{
    ra=load32(wa+1);
    //ret|=(ra<<al[off])>>ar[off];
    ret|=(ra<<al[off])>>8;
}

or jump table based 或基于跳转表

wa=byte_address>>2;
rb=load32(wa);
//if(byte_address&0xC)
ra=load32(wa+1);
switch(byte_address&3)
{
    case 0:
    {
        ret=(rb<<8)>>8;
        break;
    }
    case 1:
    {
        ret=rb>>8;
        break;
    }
    case 2:
    {
        ret=(rb<<16)>>16;
        ret|=(ra<<24)>>8;
        break;
    }
    case 3:
    {
        ret=(rb<<24)>>24;
        ret|=(ra<<16)>>8;
        break;
    }
}

I don't really understand what you mean by next section , extensible boundary and it can move . 我不太理解下一节的意思, 可扩展的边界它可以移动 Ignoring that the below code should work for reading the data: 忽略下面的代码应该可以读取数据:

int start_word = 3;
int start_byte = 2;
int end_word = 100;
uint8_t* p = data + start_word * 4 + start_byte;
uint8_t* end = data + end_word * 100;

while (p + 3 <= end) { // 3 more bytes must be available
    uint8_t b0 = *p++;
    uint8_t b1 = *p++;
    uint8_t b2 = *p++;
    if (b0 == 0 && b1 == 0 && b2 == 0)
         break;
    // do something with the 3 bytes
}

The idea is not to care too much about words and work byte-wise. 这个想法不是太在乎单词,而是按字节工作。

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

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