I don't get why I can't write mov r1, #5000
. Why I have to use ldr
instead? R1 is 32 bit register and 5000 fits in range. And as I discovered I can mov r1, #255
but can't mov r1, #256
. It seems weird for me.
问题:
回答1:
read the documentation on the instructions, in this context the instructions are fixed length, so you dont have room for both the instruction information (opcode, etc) and a 32 bit immediate in the 16 or 32 bit instruciton, not possible so some limitation on the immediate is required. With x86 for example it is variable instruction length so they can have long instructions, but it is easy to argue that doing a pc-relative load or a few fixed length instructions of the same size have no significant extra cost with a pipeline. so six of one half dozen of another. The mips fixed instruction length move immediate solution has its strengths and weakness and for each of the arm instruction sets each has its own solution with strengths and weaknesses.
for arm the assemblers (certainly gcc, probably arms toolchain, keil, etc) there is a shortcut you can do and the assembler will choose the simpler path
ldr r1,=immediate
if it cant encode it into a single instruction (note there are some move negative, math with the program counter and other tricks it can play that you might not be thinking of at the time or not knowing the pc might not be able to use), if it cannot then it may encode it as multiple instructions mov immediate then an orr, or encode it as a pc relative load.
The specific limitations for each instruction sets mov immediate is well documented in the arm architectural reference manuals, you can just get the armv7 one and it has all the encodings for that and prior architecture versions. with that knowledge you should be able to determine yourself whether or not the mov will work before having the assembler tell you.