Convert Intel x86 assembly to ARM

I am currently learning ARM assembly language;

To do this, I am trying to convert x86 code (AT&T Syntax) to ARM assembly (Intel Syntax) .

 __asm__("movl $0x0804c000, %eax;"); __asm__("mov R0,#0x0804c000"); 

From this document , I learn that on x86, piece 1 of the heap structure starts at 0x0804c000. But when I try to do the same in ARM , I get the following error:

 /tmp/ccfNZp9F.s:174: Error: invalid constant (804c000) after fixup 

I guess the problem is that ARM can load 32bit instructions.

 Question 1: Any idea what would be the first chunk in case of ARM processors? Question 2: 

From the previous question, I know how indirect memory addressing works.

Are the snippets below doing the exact same job?

 movl (%eax), %ebx LDR R0,[R1] 

I am using ARMv7 Processor rev 4 (v7l)

+4
source share
2 answers

Answer to question 1

The MOV command on ARM has only 12 bits for an immediate value, and these bits are used as follows: 8 bits for a value and 4 bits for setting the speed to the right (the speed is multiplied by 2 to increase the range).

This means that only a limited number of values ​​can be used with this instruction. It:

  • 0-255
  • 256, 260, 264, ..., 1020
  • 1024, 1040, 1056, ..., 4080
  • etc.

And so on. You get this error because your constant cannot be created using 8 bits + rotation. You can load this value into a register as follows:

 LDR r0, =0x0804c000 

Please note that this is a pseudo-instruction. The assembler will basically place this constant somewhere in your code and load it as a memory location with some offset to the PC (program counter).

Answer to question 2

Yes, these instructions are equivalent.

+1
source

Trying to learn a hand by looking at x86 is not a good idea - it is CISC and rather ugly, the other is RISC and much cleaner. Just learn ARM by looking at the instruction set link in the architectural reference guide. See the mov instruction for the add command, etc.

ARM does not use intel syntax; it uses ARM syntax.

Do not study using the built-in assembly, write a real assembly. Use the instruction set simulator first, not the hardware.

ARM, Mips and others focus on a fixed word length. So, how would you, for example, fit in an instruction that says that you need to transfer it immediately to the register, specify the register and put the 32-bit instantaneous everything in 32 bits? impossible. Therefore, for instruction sets with a fixed length of length, you cannot just load any data you need into any register. You should read the rules for this set of commands. mips allows you to execute 16 bits, a hand for 8 plus or minus, depending on the taste of the set of hand instructions and instructions. mips, where you can put these 16 bits in both the upper and lower positions, the hand allows you to put these 8 bits anywhere in the 32-bit register depending on the taste of the set of hand commands (hands, thumbs, thumb extensions )

As with most assembler languages, you can solve this problem by doing something like this

 ldr r0,my_value ... my_value: .word 0x12345678 

With CISC, which immediately is simply tied to instructions, therefore, whether it is 0 bytes or 20 bytes, it still exists with any approach.

ARM assemblers also usually allow this shortcut to be used:

 ldr r0,=something ... something: 

which says it loads r0 with the ADDRESS, and not with the contents in this place, but the address (e.g. lea)

But it can be reduced immediately

 ldr r0,=0x12345678 

which, if supported by the assembler, will allocate a memory location to store the value and generate the ldr r0, [pc, offset] command to read it. If the immediate value is in the rules for mov, then the assembler can optimize it in mov rd, # immediate.

+5
source

Source: https://habr.com/ru/post/1488074/


All Articles