What the meaning of this code with an explanation?
sub_37C2:
mov r5, r4
shr r5, #14
shl r5, #1
mov r5, [r5+0FE00h] ; DPP0
bmov r4.14, r5.0
bmov r4.15, r5.1
shr r5, #2
rets
; End of function sub_37C2
Okay, so let's start by converting the first four instructions to rough pseudocode. I'll include the instructions as comments so you can see what each one does.
r5 = r4; // mov r5, r4 - Set R5 to equal the value in R4
r5 >>= 14; // shr r5, #14 - Shift R5 14 bits to the right
r5 <<= 1; // shl r5, #1 - Shift R5 1 bit to the left
r5 = *(0xFE00 + r5); // mov r5, [r5+0FE00h] - Add 0xFE00 to R5, treat the sum as a memory address, and set R5 to equal the 16-bit value at that address.
Notice how r5 is shifted 14 bits to the right, then one to the left. At first glance it may look like this is effectively just a shift to the right by 13 bits, but any bits that are shifted out of the register are lost, and shifting to the left doesn't bring them back. So those first two shifts do add up to a 13 bit shift to the right, except it also clears the least significant bit of r5.
So the above code fragment can be simplified as follows:
r5 = r4 >> 13 & ~1
r5 = *(0xFE00 + r5)
The bmov
instruction sets one bit of a register to equal a bit in another register. You can think of it like mov
, except it works on single bits instead of entire registers at once. These two lines:
bmov r4.14, r5.0
bmov r4.15, r5.1
mean to take bit 0 (the least significant) in r5, and copy it to bit 14 in r4. Then take bit 1 in r5, and copy it to bit 15 (the most significant) in r4. In simpler terms, it sets the two most significant bits of r4 to equal the two least significant bits of r5. Adding that line, as well as the rest of the function, to our pseudocode:
r5 = r4 >> 13 & ~1;
r5 = *(0xFE00 + r5);
r4 = r4 & 0x3FFF | r5 << 14
r5 >>= 2; // shr r5, #2 - Shift R5 2 bits to the right
return; // rets - Return from a segmented function (that is, a function called using the 'calls' instruction.)
The address 0xFE00, as indicated by the comment in the disassembly, refers to a location known as 'DPP0'. This is a 16-bit register which stores the current "data page pointer", which control the mapping of 16-bit addresses to a 24-bit physical address space. Importantly, it is followed sequentially by three more 16-bit registers, DPP1
-3
. So we can think of this like an array which is being indexed, like so:
volatile uint16_t dpp[4]; // actually located at 0xFE00
r5 = dpp[r5]; // equivalent to:
// r5 <<= 1;
// r5 = *(0xFE00 + r5);
Edit: According to the comments(below of this post) I (@Unicornux) converted this piece of code to this :
uint32_t get_Value(uint16_t _arg)
{
uint32_t Value = 0;
volatile uint16_t dpp[4] = {0x302,0x403,0x706,0xA08};
uint16_t temp = _arg >> 14;
temp = dpp[temp];
_arg = (_arg & 0x3FFF) | (temp << 14);
temp >>= 2;
Value = (temp << 16) | (_arg & 0xFFFF);
return Value;
}
Explanation of the function's purpose: The function accepts a 16-bit address in r4, and determines what 24-bit physical address it represents, using the current values of the DPP registers. It returns this address as a 32-bit number, with the upper word in r5 and the lower word in r4.
sub_37C2
we have this piece of code : mov r9, #4 add r9, r0 mov r4, r9 add r4, #2 calls 0, sub_37C2
As you see, the code use stack. It seems the asm code accesses array data on the call stack, rather than in RAM. What the purpose of this code? :/
Commented
Sep 8, 2020 at 7:33
calls
instruction, and that isn't to store data on the stack.
Commented
Sep 9, 2020 at 0:59
r4
(for example 0x4920
). So, we have 2
after passing three steps. Now, According to your Hint I know: r5 = dpp[2]
. But how I can calculate the address of first element of dpp
? I wanna to find fix data of dpp array. I saw this link: studfile.net/preview/429299/page:5 So, for calculate Long Addressing Mode I did this: DPP0 = 0x1D
so: Variable Address = (0x1D * 0x4000) + 2(offset) = 0x74002 And: ROM:74000 word_74000: dw 0 ROM:74002 dw 302h ROM:74004 dw 403h ROM:74006 dw 706h
Is this correct?
Commented
Sep 10, 2020 at 7:36
temp
and _arg
were reversed in the line that sets Value, but other than that it looks good. So you should be able to answer (what I think is) your question now: what task is this function designed to perform?
Commented
Sep 14, 2020 at 0:25