Here is the instruction:
Here is an example of one register:
It's all good except op0(o0) is only one bit and all the different registers have two-bit op0s. Should I just drop the upper bit?
My understanding is that, according to the ARM documentation, the o0 field is a one bit field that determines what a complete, two bits value for op0 would be.
That is, a value of 0 in o0 is equivalent to a value of 0b10 for op0,
and a value of 1 for o0 is equivalent to a value of 0b11 for op0:
Related
Since processors follow the convention of representing numbers as 2's complement how do they know whether the number resulted from an addition of two positive numbers is still positive and not negative.
For example if I add two 32bit numbers:
Let r2 contains the value- 0x50192E32
Sample Code:
add r1, r2, #0x6F06410C
str r1, [r3]
Here an overflow flag is set.
Now if I want to use the stored result from memory in later instructions(somewhere in the code...and by now due to different instructions let the processors cpsr has been changed) as shown below:
ldr r5, [r3]
add r7, r5
As the result of the first add instruction has 1 in it's MSB i.e.now r5 has 1 in it's MSB how do the processor interpret the value. Since the correct result on adding two positive numbers is positive. Is it just because the MSB has 1, it interprets as negative number? In that case we get different results from expected one.
Let for example in a 4 bit machine:
2's complement: 4=0100 and 5=0101;
-4=1100 and -5=1011
now 4+5=9 and if it is stored in a register/memory as 1001, and later if it is being accessed by another instruction and given the processor stores numbers in 2's complement format and checks the MSB and thinks that it is a negative 7.
If it all depends upon a programmer then how do one store the correct results in reg/mem. Is there anyway that we can do to our code to store the correct results?
If you care about overflow conditions, then you'd need to check the overflow flag before the status register is overwritten by some other operation - depending on the language involved, this may result in an exception being generated, or the operation being retried using a longer integer type. However, many languages (C, for example) DON'T care about overflow conditions - if the result is out of range of the type, you simply get an incorrect result. If a program written in such a language needs to detect overflow, it would have to implement the check itself - for example, in the case of addition, if the operands have the same sign, but the result is different, there was an overflow.
I know I have covered this many times as have others.
The carry flag can be considered the unsigned overflow flag for addition it is also the borrow flag or not borrow flag for subtraction depending on your architecture. The v flag is the signed overflow flag for addition (subtraction). YOU are the only one who knows or cares whether or not the addition is signed or unsigned as for addition/subtraction it doesnt matter.
It doesnt matter what flag it is, or what architecture, YOU have to make sure that if you care about the result (be it the result or a flag) that you preserve that information for as long as you have to until you need to use it, it is not the processors job to do that nor the instruction set nor the architecture in general. It goes for the answers in the registers as it does for the flags, it is all on you the programmer. Just preserve the state if you care. This question is like saying how do you solve this:
if(a==b)
{
}
stuff;
stuff;
I want to do the if a == b thing now.
It is all on you the programmer to make that work do the compare at the time you need to use it instead of at some other time, save the result of the compare at the time of the compare and then check the condition at the time you need to use it.
for example movs r0, #immediate
Will the C flag be unchanged, undefined, zero or the last rotated bit?
Confusingly, it depends on both the instruction encoding and the constant involved. For the 16-bit Thumb encoding that use a simple immediate, APSR.C is always untouched.
For the ARM/Thumb-2 encodings using modified immediates, it depends on the expansion of the constant. Quoting from the ARMv7 ARM, "A5.2.4 Modified immediate constants in ARM instructions":
Carry out
A logical instruction with the rotation field set to 0b0000 does not affect APSR.C. Otherwise, a logical flag-setting instruction sets APSR.C to the value of bit[31] of the modified immediate constant.
Thumb-2 is similar, but with a slightly more complex definition - essentially, constants which involve rotation of the 8-bit field affect the carry flag, although those involving replication of it don't.
To illustrate all that, some examples:
Constant APSR.C
#0 unchanged
#0xFF unchanged
#0xFF0 0
#0xF000000F 1
#0xFF00FF00 unchanged (Thumb-2 only)
As Thumb mode can reference 16-bit of the general registers (r1-r14), why PC (r15) is still 32-bit? Will b Label in this mode update all 32 bits of PC, or just lower 16 bits?
Despite the question being based on an entirely incorrect premise, there is a cheeky sort-of-answer to the title question taken literally - being in Thumb mode means you're on a v4T or later architecture which means you must have a full 32 bits of PC, rather than the pre-v3 architectures where it was only 26 bits.
I'm not sure where you got the idea that Thumb operates on 16 bits of a register - the restriction with must Thumb instructions is that they can only access the "low registers" r0-r7, due to limited encoding space. There are 3 different "32-bit"s at play in ARM - the register width, the address space (which wasn't always the case as mentioned above), and the size of the fixed-width instruction encoding. Thumb only changes the third one. One result of this size reduction is that most Thumb encodings only have 3 bits per operand to encode register numbers - only a handful of instructions can spare the extra bits to encode the "high registers" r8-r15.
In operation, Thumb instructions are no different to the equivalent subset of ARM instructions - Thumb is just an alternative fetch/decode stage on the front of the same pipeline, after all.
thumbv1 instructions are 16 bits in size but what does that have to do with the size of the registers? (Nothing) the registers including r15 are 32 bits all the time. Branches with immediate values are simply offsets not absolute addresses.
this is all clearly documented in the ARM architectural reference manuals infocenter.arm.com
I am working on a software-based implementation of ARM processor in C.
Given an ARM data processing instruction:
instruction = 0xE3A01808; 1110 0 0 1 1101 0 0000 0001 1000 00001000
Which translates to: MOV r0,#8; shifted by 8 bits.
How to check whether the 8 bit shift is right or left shift?
With ARM 12-bit modified immediate constants, there is no shift, in any direction - it's a rotation, specifically, <7:0> rotated right by 2*<11:8>. Thus the encoding 0x808 represents 8 ROR (2*8), meaning 0xE3A01808 disassembles to mov, r1, #0x80000.
(Note that the canonical encoding of a modified immediate constant is the one with the smallest rotation, so mov, r1, #0x80000 would assemble to 0xE3A01702, i.e. 2 ROR 14, rather than 8 ROR 161).
As for implementing bitwise rotation in C, to solve that there's either compiler intrinsics or the standard shift-part-in-each-direction idiom x>>n | x<<(32-n).
[1] To get a specific encoding, UAL assembly allows an immediate syntax with the constant and rotation specified separately, i.e. mov r1, #8, 16. For full detail, this is all spelled out in the ARM ARM (section A5.2.4 in the v7 issue C I have here) - essentially, the choice of encodings permits a little funny business with flags in certain situations.
I'm not sure if this is what you're referring to, but here's some documentation that seems relevant:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0040d/ch05s05s01.html
The 'WITHDRAWN' pasted over the docs doesn't inspire much confidence.
It would seem to suggest a rotate right. Which plays with how I remember the barrel shifter being addressed on arm more generally (There's a ROR operation for instance, see http://www.davespace.co.uk/arm/introduction-to-arm/barrel-shifter.html)
under "The Thumb instruction set" in section 1-34 of "ARM11TechnicalRefManual" it said that:
"The Thumb instruction set is a subset of the most commonly used 32-bit ARM instructions.Thumb instructions are 16 bits long,and have a corresponding 32-bit ARM instruction that has the same effect on processor model."
can any one explain more about this especially second sentence and say how does processor perform it?
The ARM processor has 2 instruction sets, the traditional ARM set, where the instructions are all 32-bit long, and the more condensed Thumb set, where most common instructions are 16-bit long (and some are 32-bit long). Which instruction set to run can be chosen by the developer, and only one set can be active (i.e. once the processor is switched to Thumb mode, all instructions will be decoded as using the Thumb instead of ARM).
Although they are different instruction sets, they share similar functionality, and can be represented using the same assembly language. For example, the instruction
ADDS R0, R1, R2
can be compiled to ARM (E0910002 / 11100000 10010001 00000000 00000010) or Thumb (1888 / 00011000 10001000). Of course, they perform the same function (add r1 and r2 and store the result to r0), even if they have different encodings. This is the meaning of Thumb instructions are 16 bits long,and have a corresponding 32-bit ARM instruction that has the same effect on processor model.
Every* instruction in Thumb encoding also has a corresponding encoding in ARM, which is meant by the "subset" sentence.
*: Not strictly true, there is not "IT" instruction in ARM, although ARM doesn't need "IT" anyway (it will be ignored by the assembler).