Question

I am really confused and the question may sound dumb but I'm really not sure what it means when we say an instruction size is 32-bit or 16-bit.

Is it if operand size is 32-bit then we say it's an 32-bit instruction and if operand size is 16-bit instruction.

Or every instruction has opcode and if opcode address is 32-bit then we say instruction is 32-bit.

I am also going through ARM architecture where I read all thumb instruction are of 16 bit but ARM mode instruction are 32-bit.

Does instruction size totally depend upon the architecture in use or it depends on the modes in which the CPU operates?

EDIT:

http://www.xgc-tek.com/manuals/m1750-ada/m1750/x524.html

The given link suggests that 16-bit instruction is composed of 8 bits of opcode and 4+4 bits of two General Purpose register.

How is it true for ARM thumb instruction set??

Was it helpful?

Solution 2

ARM (excluding newly released 64-bit) has two instruction sets which are consisting of fixed sized instructions. Classical one is called ARM and each instruction is 32-bit. Later one is called Thumb (in fact Thumb2) which can have 32-bit or 16-bit instructions. There are ARM cores which supporting only ARM, ARM+Thumb and only Thumb instruction sets. In case a core support both modes, it has instructions to change active instruction set selection and instruction streams can jump between different sets (interworking).

ARM instructions can contain fixed operands however they can never be as big as instruction size. Some instructions also support operations on operands like shifting, rotating which gives you impression that it is possible to load 32-bit values with a single instruction.

Example #1

a = 0x1;

Thumb

2001        movs    r0, #1

ARM

e3a00001    mov r0, #1

Example #2

a = 0xC0000000;

Thumb

f04f 4040   mov.w   r0, #0xC0000000

ARM

e3a00103    mov r0, #0xC0000000

Example #3

a = 0x12345678

Thumb

f245 6078   movw    r0, #0x5678
f2c1 2034   movt    r0, #0x1234

ARM

e3050678    movw    r0, #0x5678
e3410234    movt    r0, #0x1234

OTHER TIPS

The designer of the instruction set (machine code), be it a group of people or an individual, chooses the size of the instructions. Some instruction sets, many, are variable length meaning literally that some instructions take more bits than others. The word opcode fits those legacy instruction sets well as that first byte often determined which instruction this was and from that first byte you tacked on more operand bytes. These opcodes I am thinking of, x86, 6502, z80, etc didnt necessarily have distinct fields. Switch to mips for example to see what I mean by that, fixed length instructions (although mips also has a 16 bit mode you can hop in and out of like arm). It is very easy to see where the initial decoding of some of the bits determines which of a few category of instructions, and then from there a few bits determine the instruction, called the opcode bits as well. But the term is misleading with all the instruction sets we have today. You would be right and wrong in calling the whole instruction the opcode depending on who to and what instruction set you are talking about.

So someone chooses by whatever method, experience, experiments, etc what the instruction set is and what they can cram into those bits. For the case of arm they started off with a 32 bit instruction, fixed length. Which like mips made immediates painful, but at the same time other things were easier (fetching, decoding, etc). The first thumb instructions appeared that they were being converted directly to their arm counterparts (the arm equivalent was documented in the ARM ARM) and presumably fed into the pipe as arm instructions. That was then, this is now. But it doesnt matter you define an instruction set and its machine code, and you design the logic that parses that instruction set and executes it however you want, and over time if you survive you are likely as most companies have done to re-design the processor using different logic. Take 100 programmers and give them a generic ascii file parsing task and you will get anywhere from 2 to 100 different solutions, from languages to styles to algorithms, all of which are or have the potential of doing the job. Same with processors you can invent as many different functioning processors for an instruction set as you have design cycles.

ARM has the traditional 32 bit instruction set that continues to evolve. A new instruction is added here and there but not much for major changes until the 64 bit thing. There is the original thumb instruction set, which was strictly 16 bit instructions (yes the branch is two separate 16 bit instructions, read the docs). Then they added thumb2 which used formerly undefined thumb instructions to extend the thumb instruction set to recover some of the features of the arm instruction set. these instructions have to be taken as pairs, 32 bit, to be interpreted properly. And there is jazelle which I still cant find proof that that is an actual instruction set, from everything I can figure out it is a software package that you purchase not an actual instruction set. Perhaps there are undocumented arm or thumb instructions to support jazelle but I cant see where there is an instruction set. And then arm has had a number of floating point instruction sets but they are actually coprocessor instructions with the fields renamed and mnemonics added.

The various arm processor cores use logic to decode each of these things, perhaps there is an underlying common instruction set that all of the above feeds into, microcode like but more like vliw, or perphaps it is just brute force logic, if this mode then decode these bits, etc, if that mode, etc.

The original thumb instruction set is at this point the only common instruction set spoken across the arm family. For that reason I would take some time learning it in addition to the others. The most difficult thing, which isnt difficult once you develop your habits, is to get your toolchain to build things the way you want them built, this in arm mode that in thumb or everything thumb, or everything arm. Thumb plus thumb2 extensions, or just thumb without extensions. Unfortunately armv6 added like 30 or so thumb2 instructions armv7 added another 140 or so. armv7m hit the market first, armv6m later, then single only neon and such were released, all of this creating chaos in the toolchains and users to try to generate valid code for the core in question, only generating instructions it supports and not instructions it doesnt.

The ARM ARMs, ARM Architectural Reference Manuals and the ARM TRMs, ARM Technical Reference Manuals describe the instruction sets (unfortunately some cores document in the ARM, others in the TRM), from there you can very easily see the encoding and what and where they have crammed things into ARM instructions and into thumb instructions. I would start with the oldest Architectural Reference Manual, perhaps they call that the ARMv5 ARM? I dont remember but it is the original ARM ARM and contains the ARMv4T stuff including both the arm instruction set and the original thumb instruction set. Then you need more manuals to see how those evolved.

EDIT, your link (links are bad at stack overflow, they dont survive the test of time)

MIL-STD-1750A is yet another processor family/instruction set and the machine code is broken up per that design, and decoded per that design. thumb with thumb2 extensions is basically a variable length instruction set as you have to examine the first 16 bits to determine if you need an additional 16 bits to fully understand the instruction, this is common among variable length instruction sets like the x86 family.

As far as arm and mips are concerned it is a mode thing you are in one mode or the other. As far as other instruction sets are concerned that are designed to be variable length then it isnt necessarily a mode thing, but just how the decoder works all the time. x86 did have to play games when going from 16 bit to 32 bit to 64 bit. I have not learned the new arm architecture yet, very possible that it could support 64 bit registers without a 64 bit instruction set (x86 remains an 8 bit instruction set that supports up to 64 bit registers for example) but I dont know if that is what they did.

EDIT 2

Thanks @dwelch for the detailed answer and you always there to help people.My doubt is very simple.Let say we have 16 bit instruction add r1,r2 and size of opcode is 8 bit here ,So is it mean that r1 and r2 can't have value more than 15 into it(r1 and r2 only have 8 bits to share between them).Is it true?? – 

I think auselen was trying to answer this in this way.

The machine code for an add r1,r2 simply tells the processor a few things, this is an add operation, the operands are the contents of registers r1 and r2, and the result goes into r1. No matter what r1, r2 and the other registers are always 32 bit. the instruction size has nothing to do with that. all 32 bits of r1 are added to all 32 bits of r2 and the whole 32 bit result is placed in r1.

Where it gets difficult is with immediate values. if you want to add the immediate value 1 to r1, then there is room for that. but if you wanted to add the value 0x100000 to r1, then you cannot do that with thumb mode in one instruction, you can with arm instructions and I think with thumb2 extensions but not with thumb because the design of the instruction set didnt account for that, no matter how big the instruction set you cant do everything you could ever want to do in a single instruction. For thumb to add that constant to a register you would need to consume another register, and then either load that constant from memory (by asking the assembler to place that value in memory when building the binary) or you could for example mov 1 into a register, then shift it left 20 bits. and then do the add of that register which now contains 0x100000 with r1 using add r1,r2 assuming r2 is where you placed that constant.

Mips and arm use different ways to get their immedates to work within the fixed length instructions, mips basically gives you a high 16 bits or low 16 bits and has a cluster of instructions where half the instruction is immediate. Arm in general breaks it down into 8 bits and a shift operand so that you can create any immediate so long as the unique bits are in an 8 bit cluster (plus some other rules). To use pure instructions mips takes two instructions to load any possible 32 bit value into a register, arm takes up to 4 in arm mode. thumb mode takes more than that.

Back on topic, look at the x86 instruction set a single 8 bit opcode can tell the processor to perform some operation on two 64 bit registers. That is not just an 8 bit opcode but the entire instruction is only 8 bits. Sometimes 16, sometimes more. but the point is the instruction specifies which register which only takes a few bits. the size of the register is part of the instruction set design but does not have to be and often isnt tied to the size of the instructions. r1 and r2 can have values anywhere between 0x00000000 and 0xFFFFFFFF inclusive for any operation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top