What is the Berkeley DB Magic Number? - berkeley-db

What is the magic number for a Berkeley DB v9 Btree with a native byte order? Is there any specific length on magic numbers or any easy way to identify them?

As you've found it's 0x00053162. I'm assuming by native byte order, you mean x86 native byte order? If you hexdump the file, you'll see it in bytes 12-15, byteswapped (as 3162 0005, because it's x86):
hexdump blah.db | head -1
0000000 0001 0000 9fbc 0009 0000 0000 3162 0005
0000010 0009 0000 1000 0000 0900 0001 0000 0000
The version is in the next uint32_t, bytes 16-19. Here, it's 0009 0000, which is version 9 in little endian-speak. In fact, that whole sequence of bytes starting at offset 12 looks to be a struct __db_bt_stat, the content of which is given in the manpage for db_stat (or Db::stat) available here: http://www.mit.edu/afs.new/athena/astaff/source/src-9.0/third/db/docs/api_cxx/Db/stat.html

Related

How to convert 0x80 in a 7-bit variable-length integer?

Im reading a book about network protocol structures.
There is an illustration in a chapter about variable-length quantity, which I dont fully understand.(see attachment)
The subject is to convert different numbers to variable-length 7-bit integers.
The first line shows that 0x3F is stored in a single octet as 0x3F.
The second line shows that 0x80 is stored in two octets one as 0x80 and second as 0x01.
However I dont understand why its not 0x81 in the first octet and 0x00 in the second.
Because according to wikipedia, converting numbers into variable-length 7bit integers goes as follows:
Represent the value in binary notation (e.g. 137 as 10001001)
Break it up in groups of 7 bits starting from the lowest significant bit (e.g. 137 as 0000001 0001001). This is equivalent to representing the number in base 128.
Take the lowest 7 bits and that gives you the least significant byte (0000 1001). This byte comes last.
For all the other groups of 7 bits (in the example, this is 000 0001), set the MSB to 1 (which gives 1000 0001 in our example). Thus 137 becomes 1000 0001 0000 1001 where the bits in boldface are something we added. These added bits denote if there is another byte to follow or not. Thus, by definition, the very last byte of a variable length integer will have 0 as its MSB.
So lets do these steps for 0x80:
binary notation: 1000 0000
in groups of 7 bits starting from LSB: 0000001 0000000
and 4. set MSB as described: 1000 0001 0000 0000
Converting that binary number into two hex octets, gives me 0x81 and 0x00.
Which leads me to the question: Is there a printing fail in the book or did I missunderstood something?
Which book is that?
There may be many possible encoding schemes. One of them could go like this:
1. Represent the value in binary notation (e.g. 0x80 as 10000000)
2. Break it up in groups of 7 bits starting from the lowest significant bit: 0000001 0000000
3. Start with the lowest 7 bits: if this is *not* the last group of 7 bits, then set MSB: 10000000; if it's the last, then leave it
alone: 00000001
4. Output starting LSB first: 10000000 00000001, i.e. 0x80 0x01
So what does the book say? What encoding scheme are they using?

Convert 2 digit hex op code format into 6 binary digit opcode

I was going through an old exam paper and was doing a question to convert sw $6, -4($7) into machine code in hex.
I was used to the format where the opcode is 6 digits long and set. If you Google, the opcode for sw is 101011. However, in this exam paper, it had a table of opcodes where the opcode was Ox2B which for me translates as 0010 1010. Now, if I was to see this exam question, how would I convert this 8 digit opcode into the 6 digit one I need? What is the rule system for this?
You made an error in your translation: 0x2B translate to 0010 1011 (so indeed opcode 10 1011), not 0010 1010.

What is the decimal equivalent of the 32-bit IEEE floating point value CC4C0000?

First thing I do is to convert it into binary and so I get
CC4C0000 = 1100 1100 0100 1100 0000 0000 0000 0000
Now I know the number is negative because the sign bit (the first bit in the binary representation is 1).
And the exponent is the next 8 bits which is 10011000 which is equal to 2^7 + 2^4 + 2^3 = 128 + 16 + 8 = 152
Now the fractional part is the remaining 23 bits 100 1100 0000 0000 0000 0000.
Now here is my question , what is the true exponent ?
It should be 152-127 = 25 right ?
The fractional part is .100 1100 0000 0000 0000 0000
And after reinserting the leading one we have 1.100 1100 0000 0000 0000 0000.
Now I know that .100 1100 0000 0000 0000 0000 is equal to 0.59375
And so the final answer should be -1.59375 x 2^25.
But why it is not the correct answer.
When I put cc4c0000 in this url
http://www.h-schmidt.net/FloatConverter/IEEE754.html
The answer is different , where is my error if any ?
Thanks for any help :)
Your train of thought is correct and you did not make any mistakes.
-1.59375 * 2^25 = -53477376
Which is exactly the answer the webapp you linked gives me. Double check that you didn't make any silly errors during the final multiplication.
There are a couple of assumptions here:
Bytes are in "Network" order (i.e. more significant bytes first)
Format is IEEE 754 (but in fairness I don't know what other IEEE format it could be ..)
Using Python I can use unhexlify command to convert your hex-string data as a string of bytes and then struct.unpack to read it in as IEEE 754 ...
struct.unpack('!f', unhexlify('CC4C0000'))
(-53477376.0,)
I can't say for sure if this is the "correct answer" for you given assumptions, but it should give you a tool with which to determine it.
The documentation for python struct module is here: https://docs.python.org/2/library/struct.html#format-characters

How to calculate size of memory by given a range of address?

I have an exercice that I couldn't resolve it,
I have 3 memory range :
First # Last #
range1: FD00 0000 to FDFF FFFF
range2 : D000 0000 to DFFF FFFF
range3 : FA00 0000 to FBFF FFFF
the question is :give the size of the memory for each range (Mega byte)?
what I know is that I should calculate size of the range = last address - first address
so the result for the first range is : 00FF FFFF .
Is this right? then what should I do? I have searched on the internet I didn't found an example
Please help
In your example for Range 1, you are correct. That is the size of the memory, stated in hexidecimal, in bytes.
You may gain the most insight by first converting 00FF FFFF to a decimal number, then converting that number of bytes into megabytes.
To convert from bytes to megabytes use the relationship
1 MB = 1 Megabyte = 1024 * 1 KB = 1,048,576 bytes.
There are tons of online Hex to Decimal converters. The calculator built in to Windows can also do the conversion.
For the other ranges, you again want to do subtraction to determine the size of the range, and then apply the steps above, e.g.
FBFF FFFF
-
FA00 0000
---------
01FF FFFF
Having gone through those steps to better grasp what is happening, the following relationship will allow you to answer such questions faster:
0010 0000 = 1,048,576
So 1MB is the same as 0010 0000 (sometimes called 0x100000).
Sorry, to answer a question with another question/s...
Isn't the number of addresses available within a stated range inclusive of those range limiters aswell?
e.g. (in decimal to illustrate my point) with a start address 5, and an end address of 10. With subtraction only i.e. end address minus start address (10-5) we get a range of 5.
But there are actually six unique addresses in the range i.e. 5,6,7,8,9,10 (so we should add 1 to the result of the subtraction in Julie's original question?)
Also, memory address size versus actual memory size. Are we talking about the number of individual memory locations or the size of the memory available to store data in (which should take into account the size of each location)?
If its just memory locations, then we are almost done (I think this is referred to as memory address size). Just have to work out the MB part of the question (I'll come to that issue at the end)
If its the available storage space, this should include the size of each addressable portion of memory e.g. each address location holds an unknown sized chunk of data. Say if it is 1 byte (1B) of data per memory location than my example above means the memory size is:
6 (memory locations) multiplied by 1 Byte (volume of each memory location)for a total memory size of 6B
So based on my logic, the answer to original question for Range 1 should be 01000000hex (range1 = FDFF FFFF-FD00 0000 + 1 = 01000000h).
As for the memory size of that range, this is where I get really confused....
It is a specific number of memory locations i.e. 1000000h, of some undetermined size for each location. So why express it in MB or GB. If you do know the size of each memory location (and multiply number of locations by by the size of each location, then you have the memory size for that range and can express it in numerical form.
And while we are at it, where I get really really confused is the use of MB, GB etc. It is often cited as each prefix equates to a multiple of 1024 e.g. 1KB = 1024Bytes, 1MB = 1024kB etc but the IEC preferred convention is based on the ISO standard (according to my googling just now) which says Kilo (kB) = 1000, Mega (MB) = 1000000 etc.
So putting the unknown size of each location aside, and converting 1000000h to decimal i.e. 16,777,216 the answer is either:
16MB (16777216/1024/1024=16) I SUSPECT THIS IS THE ANSWER THE TEACHER IS AFTER
16.777216MB (according to the ISO standards)
16 mebibytes (according to the joint IEC/ISO standard - IEC 80000-13)
Btw, Googling only just educated me (may be taken to mean recently and partially) on kibibytes and mebibytes...if you're interested, check out https://en.wikipedia.org/wiki/Kilobyte
the equation is
second_add - first_add + 1
example
fdff ffff - fd00 0000 + 1 = 0100 0000 = 2^24 = 2^4 * 2^20 = 16Mbyte [2^20 byte = 1 Mbyte]
Simple analogy, what is amount range (address) from 0 - 9?
The answer is 10, not 9 because range/address 0 is counted.
So,
Capacity = Last Address - First Address + 1.
Capacity for range1: FD00 0000 to FDFF FFFF will be
FDFF FFFF - FD00 000 + 1 = FF FFFF + 1 = 100 0000 in hex
Or 16777216 in dec (16MB).
I think the formula
size = end - begin
is always ok to use (no difference from other sizes, i.e. waist for pants)
memory size makes it bit harder due to HEX and DEC, in which decimal is easy for human to read, and often B(Bytes) is used.
to make things easy, if you have bc installed, you may want to try
echo 'ibase=16;yourendhex-yourbeginhex' | bc
in your case
echo 'ibase=16;FDFFFFFF-FD000000' | bc
echo 'ibase=16;DFFFFFFF-D0000000' | bc
echo 'ibase=16;FBFFFFFF-FA000000' | bc
16777215 #16MB
268435455 #268MB
33554431 #34MB
To make it easy for you to understand I just change the question as follows, what is the size of memory of a range of 2-9?.
The answer is 8 as follows 2, 3, 4, 5, 6, 7, 8, 9. The formula is the highest address-lowest address + 1.
For your first problem range1: FD00 0000 to FDFF FFFF, the answer is 00FF FFFF+1=0100 0000H=1 X 16^6= 1 X (2^4)^6=2^24=2^4 x 2^20. For in binary system 2^10= 1024=1K and 2^20=1K x 1 K = 1M then 2^4 x 2^20=16 M. For the second and the third problem please kindly do the same. Good luck.
range1: FD00 0000 to FDFF FFFF:
FD FF FFFF
- FD 00 0000
------------
FF FFFF +1 = 1MB (0x100 0000)
range2 : D000 0000 to DFFF FFFF = 256MB (0x1000 0000)
range3 : FA00 0000 to FBFF FFFF = 32MB (0x200 0000)
It should be noted that +1 is added since both number are exclusive here

Subtracting a large unsigned binary number from a smaller one

I'm taking a computer organization and assembly language course. The written part of our lab this week has a question on it that has me stumped. The question reads...
Subtract the following unsigned binary numbers (show the borrow and overflow bits). Do not convert to two's complement.
0101 0111 1101
-1110 1011 0110
--------------
I realize that the answer is -1001 0011 1001 but I'm having a hard time trying to figure out how to borrow to actually perform this subtraction by taking the larger number and subtracting it from the smaller number and show my work. My whole life when subtracting a large number from a small number I have reversed the problem and instead subtracted the smaller number from the larger number and added a negative sign in front of the result. I asked the professor and he says that he wants the problem solved the way that it is written. I am not allowed to solve this by subtracting the smaller number from the larger number and negating like I normally would. I haven't been able to find any examples online of subtracting a larger unsigned binary number from a smaller one.
I would really appreciate it if someone could describe to me how to perform subtraction in this scenario.
Update:
#Alex is correct. The professor was looking for
0110 1100 0111 (1735)
Thanks everyone.
You do it the same way irrespective of which number is bigger and which is smaller.
bb b bb <- borrows
0101 0111 1101 (1405)
-1110 1011 0110 (3766)
--------------
0110 1100 0111 (1735?)
Now, if you want a proper difference, you need to take into account the overflow since the above result doesn't include the sign bit:
b bb b bb <- borrows
0 0101 0111 1101 (1405)
-0 1110 1011 0110 (3766)
----------------
1 0110 1100 0111 (-2361 signed 2's complement)
Really, the CPU doesn't care what gets subtracted from what. It uses the same algorithm for integer addition/subtraction, moreover, this algorithm is the same for signed and unsigned integers. You only have to correctly interpret the result and the carry and overflow flags. That's all.
simply subtract the two binary numbers as they are, then take the 2's complement of the result. voila!

Resources