26

このページと他のさまざまなガイドを使用して、非常に単純な ARM 命令をバイナリと 16 進数で表現する方法を見つけようとしました。私には簡単なプロセスのように思えますが、まだ理解できません。いくつかの例を次に示します。

基本 NOP:

       what goes here?          what goes here?
             _↓_                  _____↓____
            |   |                |          |
mov r0, r0 ; ????00?1101?????????????????????
                         |__||__|
                          ↑    ↑
                 how do I express registers?

他の人への同じ基本的な質問。

2 つのレジスタの比較:

cmp r1, r0

即値をレジスタ値に追加:

add r0, #0x1a

オンラインのこれらのチュートリアルはすべて、このような命令の使用方法を説明するのに優れていますが、ARM 命令をバイナリ/16 進数/マシン コードに変換してアセンブルする方法を実際に説明しているものはありません。

よろしくお願いします。

4

3 に答える 3

36

データ処理命令のコーディング方法は次のとおりです。

ARM データ処理命令

あなたのそのページに条件コード表があります。レジスタは でコーディングされ0000ます1111

あなたの例はすべて同じカテゴリに分類されます。写真は私の HDD のドキュメントから抽出したものですが、Googleで検索することもできました。これらの命令をコーディングするのは面倒な作業です。

したがって、mov r0, r0次のようになります。

1110 00 0 0 1101 0000 0000 00000000

実際には に適用できないため、Rn を 0 にしMOVます。の場合、常に 1CMPだと思います。S

于 2012-08-02T22:02:55.870 に答える
13

First off, you need the ARM Architectural Reference Manual (ARM ARM) at infocenter.arm.com, reference manuals, get the oldest one (armv5 or whatever). the instruction set is well defined in there.

Second, why dont you just assemble some instructions and see what happens?

;@test.s
cmp r1, r0
add r0, #0x1a

whatever cross assembler you have (see http://github.com/dwelch67/raspberrypi in the build gcc directory for a script, just run up thru binutils in that script)

arm-none-linux-gnueabi-as test.s  -o test.o
arm-none-linux-gnueabi-objdump -D test.o

arm-none-linux-gnueabi vs arm-none-elf vs arm-elf, etc dont matter for this, all do the same

Disassembly of section .text:

00000000 <.text>:
   0:   e1510000    cmp r1, r0
   4:   e280001a    add r0, r0, #26

The top four bits of a full 32 bit arm instruction (not thumb) are the condition code, see the condition field section in the ARM ARM. an 0xE means always, always execute this instruction. 0b0000 is eq only execute if the z flag is set, 0b0001 ne only execute if z is clear, etc.

In the ARM ARM push into the arm instruction set, then alphabetical list of arm instructions, then find cmp It starts with cond 00I10101 rn sbz shifter

From our cmp instruction above we see 1110 000101010001 ... so I is a zero bits 15:12 are zero bits 27:26 are zero and 24:21 are 1010 so this is a cmp instruction

bits 19 to 16 above are 0b001 which is rn so rn = 1 (r1) for the shifter operand in the ARM ARM it tells you to look at Addressing Mode 1 Data Processing operands and has a link in the pdf to the page

we know we want the second operand to simply be a register, that is called data processing operands - register, and a page number, go to that page on that page 15:12 is rd 11:4 are zeros and 3:0 is rm. we know from the cmp instruction it says 15:12 should be zero, I wonder if it cares, a cmp does not store a result to a register so rd is not used. rm is used and in this case we want r0, so 0b0000 goes in 3:0 also note that it shows bits 27:25 as zeros, in the cmp instruction 25 is I, we now know that we want a zero there so

between the cmp page and this data processing - register page we have the whole picture

1110 condition
000 
1010 opcode
1 S (store flags, that is a 1 for a cmp to be useful)
0001 rn
0000 rd/dont care/sbz
00000
000
0000 rm

cmp rn,rm
cmp r1,r0

the add is similar but uses an immediate, so go to the add instruction in the alpha list of instructions. we now know from the cmp that 24:21 for this class of instruction is the opcode, we can pretty much go straight to the shifter operand stuff to continue from there

this time we are doing add rd,rn,#immediate

so look for the page for #immediate

and the encoding is

1110 condition, always
001 (note the immediate bit is set)
0100 (opcode for add for this type of instruction)
0 (S not saving the flags, it would be adds r0,r0,#26 for that)
0000 (rn = r0)
0000 (rd = r0)

now comes the interesting part, we can encode the 26 different ways. bits 7:0 are the immediate and bits 11:8 allow that immediate to be rotated, 26 is 0x1A, we could just simply put 0x1A in the lower 8 bits and set the rotate to 0, and that is what gnu assembler did. could probably put a 0x68 in the lower 8 bits and a 1 in the rotate_imm field 1101000 rotated right 1*2 bits is 11010 = 0x1A = 26.

于 2012-08-02T22:25:44.080 に答える
7

すべての命令のエンコーディングについて説明している ARM ARM のコピーを入手する必要があります。

ほとんどの ARM 命令は、条件コードに上位 4 ビットを使用します。命令を条件付きで実行したくない場合は、疑似条件 AL (1110) を使用してください。

エンコーディングの最初のレジスタ (Rn) は MOV 命令には使用されず、ARM ARM で定義されているように 0000 に設定する必要があります。

2番目のレジスタは宛先です。ここではレジスタ番号をエンコードするだけなので、r0を宛先として使用しているため、この場合も0000になり、r4の場合は0100になります.

残りは、非常に柔軟な、いわゆるシフター オペランドです。あなたの場合(r0)のように単純なレジスタである可能性があり、最後の4ビットが再びレジスタをエンコードするのは0000 0000 0000です。また、データ処理用のレジスタまたは即値を使用して、さまざまなタイプのシフトおよび回転をエンコードすることもできます。

しかし、下位ビットで 8 ビットがエンコードされ、最初の 4 ビットが 2 ビット単位で右回転を定義するイミディエートの場合もあります。この場合、bit25 も 1 になり、それ以外の場合はすべて 0 になります。

于 2012-08-02T22:06:04.127 に答える