How to combine digital value in ADRESH and ADRESL into a register to implement mathematical equation?

Thread Starter

thanhnhonn7

Joined May 25, 2020
4
Hello all,
I'm stuck in finding out how come the two discrete 8-bit register (ADRESH and ADRESL) can be combined to 16-bit register by multiplying ADRESH with 256 then add the result with ADRESL value whereas there isn't any 16-bit register in PIC 18 data memory. I found this method on Internet and this seems to work correctly because it has been applied for most of projects. Hope you guys clarify it. Thank you!
 

MrChips

Joined Oct 2, 2009
30,618
ADRESH and ADRESL are 8-bit registers. They represent the high byte and low byte of a 16-bit value.
Hence in order to combine the two you only need to put them side by side in the correct order:

[high order 8 bits] [ low order eight bits]

It is the same as putting the numerals 1, 2, 3 together to make decimal 123.
In this example note that the final value is (1 x 100) + (2 x 10) + (3 x 1)
since this is base-10.

Similarly the 16-bit value is
( [high order 8 bits] x 256 ) + ( [ low order eight bits] x 1 )
since this is base-256.

If you think about it, multiplying by 256 is the same as shifting left 8 bits.
Shifting left is more efficient than multiplying.

Hence this is better:
RESULT = (ADRESH << 8 ) + (ADRESL)
 

Thread Starter

thanhnhonn7

Joined May 25, 2020
4
ADRESH and ADRESL are 8-bit registers. They represent the high byte and low byte of a 16-bit value.
Hence in order to combine the two you only need to put them side by side in the correct order:

[high order 8 bits] [ low order eight bits]

It is the same as putting the numerals 1, 2, 3 together to make decimal 123.
In this example note that the final value is (1 x 100) + (2 x 10) + (3 x 1)
since this is base-10.

Similarly the 16-bit value is
( [high order 8 bits] x 256 ) + ( [ low order eight bits] x 1 )
since this is base-256.

If you think about it, multiplying by 256 is the same as shifting left 8 bits.
Shifting left is more efficient than multiplying.

Hence this is better:
RESULT = (ADRESH << 8 ) + (ADRESL)
This is just reasonable unless ADRESH is already a 16 bit register because if shifting ADRESH left 8 bit will result in 0x00 in this one. Moreover, how to declare adress of RESULT valuable while General Purpose Registor are 8-bit length. Sorry but i still don't understand how it works, especially in Assembly language. Hope you to give me an example for this problem, please!
 

MrChips

Joined Oct 2, 2009
30,618
But ADRESH is not 16-bit register. It is an 8-bit register.
If you are writing in C you declare RESULT to be 16-bit variable.

If your MCU has 16-bit registers then here is the solution:
Load reg16 with ADRESH
Swap bytes (if MCU does not have SWAP instruction then shift left 8 bits)
Add ADRESH to reg16

If your MCU has 8-bit registers then there is nothing else you need to do:
Load resultH with ADRESH
Load resultL with ADRESL
 

Thread Starter

thanhnhonn7

Joined May 25, 2020
4
But ADRESH is not 16-bit register. It is an 8-bit register.
If you are writing in C you declare RESULT to be 16-bit variable.

If your MCU has 16-bit registers then here is the solution:
Load reg16 with ADRESH
Swap bytes (if MCU does not have SWAP instruction then shift left 8 bits)
Add ADRESH to reg16

If your MCU has 8-bit registers then there is nothing else you need to do:
Load resultH with ADRESH
Load resultL with ADRESL
More specific about my project, I'm using PIC18F and writing in assembly language. This MCU only has 8 bit registers with a specified address. So after loading value of ADRESH and ADRESL into resultH and result L ( assume that i configured these register at the begining with 2 consecutive address in GPR memory), If i need to get the result of ADC conversion to serve for an equation, what should I use resultH or resultL valuable? So combining two register is the first step, isn't it? But how come? Or Is there any misunderstanding about PIC memory?
 

MrChips

Joined Oct 2, 2009
30,618
It is not a misunderstanding about PIC memory. It is a misunderstanding about all computers.
A computer might have register widths of 4, 8, 10, 12, 16, 32, 60, 64, 80, etc, i.e. any size register.
This does not prevent it from doing 64-bit arithmetic.

Let us take a simple example. Suppose your MCU only has 8-bit registers.
How would you add two 16-bit values?
One number is AH,AL.
The second number is BH,BL.
The result is RH,RL.

Now perform 16-bit addition so that R = A + B.
 

atferrari

Joined Jan 6, 2004
4,763
You mention in the OP something you found in the Web. What is that?

Your expresion "combining" sounds strange. Other than putting the values side by side to read them as a 16-bit number, you do not "combine" them in any other way. You operate with them as 8-bit entities always. Do not try to force a concept that is wrong.

The 18F datasheet gives the algorithm for 16 bit operations. Simply follow that.
 

BobaMosfet

Joined Jul 1, 2009
2,110
Hello all,
I'm stuck in finding out how come the two discrete 8-bit register (ADRESH and ADRESL) can be combined to 16-bit register by multiplying ADRESH with 256 then add the result with ADRESL value whereas there isn't any 16-bit register in PIC 18 data memory. I found this method on Internet and this seems to work correctly because it has been applied for most of projects. Hope you guys clarify it. Thank you!
This is because you don't understand binary.

An 8-bit register can only hold 256 distinct values (0-255). If you try to put 256 into an 8-bit register, it becomes zero because the bit that would equal 256 is pushed off the end of the register (into the void).

1590607425918.png

In the above example, the binary value: 10000110 in decimal is: 128+4+2 = 134 since 256 is more than an 8-bit register can hold, you have to have 2 such registers side by side to form a 16-bit register.

256 in binary = 0000 0001 0000 0000

The left 8 bits have the following values:

32768 | 16384 | 8192 | 4096 | 2048 | 1024 | 512 | 256

The right 8-bits have the values shown in the image above. So...

0 + 0 + 0 + 0 + 0 + 0 + 0 + 256 + 0 + 0 +0 + 0 + 0 + 0 + 0 + 0 = 256.

When you multiply by 256, you're actually pushing the value left by 8 bits.

0x01 (hex) = 00000001 (binary) = 1 (decimal). 1 << 8 = 256

1 * 256 = 256.

So if you have two registers, each containing these values:

High 8-bit Register; 93 (0x5D hex)
Low 8-bit Register: 23 (0x17 hex)

You can multiple 93 * 256 = 23,808 (0x5D00 in hex) and then you add 23 (0x17 in hex).
23,808 + 23 = 23831 (0x5D17 in hex)

This is why understanding how to move between decimal, hex, and binary is critical (and so very easy). Hex makes it simple to do in your head.
 

MaxHeadRoom

Joined Jul 18, 2013
28,576
All 18f devices have a built in hardware 8x8 multiplier and also displays 16x16 un-signed as well as 16x16 signed multiplication
The section Hardware Multiplier in the manual will show this.'

"All PIC18 devices include an 8 x 8 hardware multiplier
as part of the ALU. The multiplier performs an unsigned
operation and yields a 16-bit result that is stored in the
product register pair, PRODH PRODL. The multiplier’s
operation does not affect any flags in the STATUS reg"
Max.
 
Top