0
votes

I'm dealing with cache questions and there I need to split the address into tag/set/offset. For example I have the address 0xFFFFFE7D6C5B4333 and for example the offset contains 5 bits (The offset is the first block from the right of the address). Then I would have to convert the hex address into binary, remove the first 5 bits and convert it back to hex. This process could take some time and it can lead to some mistakes. If the number of the offset bits was of format 4*c then it could be easy because I would just remove the first right c numbers from the hex code.

Is there a better way to do it when the number of the offset bits is not of format 4*c (for example 5)?

For example for 0xFFFFFE7D6C5B4333 we get:

1111 1111 1111 1111 1111 1110 0111 1101 0110 1100 0101 1011 0100 0011 0011 0011

We remove the first five bits and we get:

1111 1111 1111 1111 1111 1110 0111 1101 0110 1100 0101 1011 0100 0011 001

Back to hex: 0x7FFFFF3EB62DA19

1
Your example shows that when you remove from the little end, you pad zeros on the big end. That isn't obvious in the request.kainaw

1 Answers

0
votes

I suggest converting to a decimal (or binary) number, shifting, and converting back. The problem is that you are using large integers. Most programming languages have support for arbitratily large integers. For example, PHP has a BC library. Using that, I can quickly write functions to convert between hex and dec in BC. I can write a shift by dividing by 2 multiple times. Then, I can perform your example. It is essentially three function calls: bchexdec, bcshift, and bcdechex.

<?php
$hex = "FFFFFE7D6C5B4333";
print "HEX = $hex\n";
$dec = bchexdec($hex);
print "DEC = $dec\n";
$dec = bcshift($dec,5);
print "DEC = $dec\n";
$hex = bcdechex($dec);
print "HEX = $hex\n";

function bcshift($dec,$n) {
    for($i=0; $i<$n; $i++) {
        $dec = bcdiv($dec,"2");
    }
    return $dec;
}
function bchexdec($hex)
{
    $dec = 0;
    $len = strlen($hex);
    for ($i = 1; $i <= $len; $i++) {
        $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
    }
    return $dec;
}
function bcdechex($dec) {
    $hex = '';
    do {
        $last = bcmod($dec, 16);
        $hex = dechex($last).$hex;
        $dec = bcdiv(bcsub($dec, $last), 16);
    } while($dec>0);
    return $hex;
}
?>

So, your problem is actually writing those three functions in whatever programming lanugage you want to use. Then, if you do this often, write a function that wraps those three function calls.