# How to load immediate negative value in a register?

For example on 8-bit AVR given a register r16 I do something like ldi r16, 44 and this way I can give it positive values from 0 to 255. But if I want negative clearly in two's complement I can get a range of -128...+127 but I can't do that like.

ldi r16, -13

And furthermore how does the microprocessor know whether I want all 8-bits for positive 0...255 or negative -128 to 127? Thank you very much for your help.

how does the microprocessor know whether I want all 8-bits for positive 0...255 or negative -128 to 127?

The processor doesn't know and doesn't care.

The advantage of using two's complement representation for signed numbers is that add and subtract operations produce the same results from the same inputs whether you say the inputs are unsigned or two's complement values.

Of course you will have to watch out for different overflow conditions in the two cases --- but typically the processor provides flags that can detect overflow for either type of operation.

But if I want negative clearly in two's complement I can get a range of -128...+127 but I can't do that like.

ldi r16, -13

If you can't, that's a limitation of your assembler, not of the processor.

If you use the Microchip AVR Assembler, you should be able to exactly that, according to the documentation.

• But then how can I give an 8-bit register a value of 255 if the range of two's complement representation is -128 to 127? – mcdonald reversed Aug 18 '18 at 20:20
• You can load the register with a binary 11111111. You can then interpret that as an unsigned 255 or a two's complement -1. As long as you're consistent it won't change the binary result of an add or subtract operation. – The Photon Aug 18 '18 at 20:23
• The processor doesn't care whether the register contains a two's complement number or plain binary number, or even an ASCII character - it just sees the contents of the register as a bit pattern. It is up to your software to interpret the bit patttern as you require. – Peter Bennett Aug 18 '18 at 20:37

The microprocessor does not differ. You're the one who should know. In a high-level language such as C, there are both signed and unsigned data types. You can do, for example, int a = -5*b, making it clear that you want a signed multiply. But in Assembly, loading an 8-bit register with 0xFF can either mean 255 as -1. The binary pattern of the result is the same when adding signed or unsigned values. Also, this is true for multiplication if the result has the same length as the operands. If the result has a bigger length, there is an instruction for unsigned multiply and other for signed multiply. The microporcessor flags, such as overflow, carry (unsigned overflow) and zero are sensitive to the result of operations, being useful for execute jumps according. The programmer is responsible for the correct interpretation.