2012-08-02 2 views
21

나는 매우 간단한 ARM 명령어를 2 진수 및 16 진수로 표현하는 방법을 이해하기 위해 this page과 같은 다양한 가이드를 사용하려고 시도 해왔다. 그것은 나에게 간단한 과정이어야하는 것처럼 보입니다. 그러나 나는 여전히 이해하지 못합니다. 몇 가지 예가 있습니다.매우 간단한 ARM 명령어를 2 진수/16 진수로 변환

기본 NOP : 다른 사람에 대한

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

같은 기본적인 질문입니다.

비교 두 레지스터 :

cmp r1, r0 

값 레지스터에 추가 :

온라인
add r0, #0x1a 

이 자습서의 모든 다음과 같은 지침을 사용하는 방법을 설명에서 우수를, 그러나 아무도 내가 할 수 없었다 ARM 명령어를 어셈블하는 바이너리/헥스/머신 코드로 ARM 명령어를 변환하는 방법을 실제로 살펴보십시오.

미리 도움을 주셔서 감사합니다. 여기

+2

큰 질문; 불행히도 링크가 죽었습니다. 지나가는 사람들을위한 빠른 [웹 아카이브 링크] (https://web.archive.org/web/20150426195854/http://www.nyx.net/~troddis/ARM.html) – Asu

답변

29

데이터 처리 명령을 코딩하는 방법입니다

ARM data processing instructions

당신은 당신의 해당 페이지의 조건 코드 테이블을 가지고있다. 레지스터는 0000부터 1111까지입니다.

모든 예는 동일한 카테고리에 속합니다. 사진은 내 HDD의 일부 문서에서 추출되었지만 google까지 찾을 수있었습니다. 이러한 지침을 코딩하는 것은 지루한 작업입니다.

그래서, mov r0, r0은 다음과 같이 가야한다 : 실제로 MOV에 적용되지 않기 때문에

1110 00 0 0 1101 0000 0000 00000000 

내가 0으로 Rn에 넣어. CMP의 경우 S은 항상 1입니다.

5

모든 지침은 인코딩에 대해 설명하는 ARM ARM 사본을 받아야합니다.

대부분의 ARM- 명령어는 조건부 코드에 상위 4 비트를 사용합니다. 조건부로 명령을 실행하지 않으려는 경우 의사 조건 AL (1110) 만 사용하면됩니다.

인코딩의 첫 번째 레지스터 (Rn)는 MOV 명령어에 사용되지 않으며 ARM ARM에서 정의한대로 0000으로 설정해야합니다.

두 번째 레지스터는 당신이 0100

것 R4를 들어, destinal으로 R0을 사용하고 있기 때문에 그것은 또한 0000 것입니다 귀하의 경우, 그래서 당신은 단지, 레지스터 번호를 인코딩 여기에 대상입니다 나머지는 매우 유연한 이른바 시프터 피연산자입니다. 그것은 귀하의 경우 (r0)에서 간단한 레지스터가 될 수 있으며 그것은 단지 0000 0000 0000이며 마지막 4 비트는 다시 레지스터를 인코딩합니다. 또한 다양한 유형의 시프트를 인코딩 할 수 있으며 데이터 처리를 위해 레지스터 또는 즉시 값으로 회전 할 수 있습니다.

그러나 8 비트가 하단 비트에서 인코딩되고 처음 4 비트가 2 비트 단계에서 오른쪽 회전을 정의하는 바로 그럴 수도 있습니다. 이 경우 비트 25도 1이되고 다른 모든 경우는 0이됩니다.

+5

ARM ARM은 재미있는 두문자어이지만, 구글 검색을하기가 어렵다. 확장은 'ARM 아키텍처 참조 설명서'로, 여기 [http://infocenter.arm.com/help/topic/com.arm.doc.subset.architecture.reference/index.html#reference]에서 사용할 수 있습니다.) 무료 등록 후. –

+0

@Kevin No, 확장은 실제로 ** 고급 (명령어 세트 컴퓨팅 감소) 머신 아키텍처 참조 매뉴얼 **입니다. 하지만 그건 좋은 구글 검색되지 않습니다 :) –

9

먼저 infocenter.arm.com에서 ARM 아키텍처 참조 설명서 (ARM ARM)가 필요하며 참조 설명서는 가장 오래된 것 (armv5 또는 무엇이든). 명령어 세트는 거기에 잘 정의되어있다.

두 번째 이유는 몇 가지 지침을 조합하고 어떤 결과가 발생하는지 보지 않겠습니까?

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

어떤 크로스 어셈블러 당신이 (그냥 스크립트에서 바이너리 유틸리티를 통해 최대 실행 스크립트의 빌드 GCC 디렉토리에 http://github.com/dwelch67/raspberrypi 참조) 팔걸이 대

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

팔 - 없음 - 리눅스 - gnueabi 그럼에도 ELF 등 아암 ELF VS 모두가 전체 32 비트 ARM 명령어 (되지 엄지) 조건 코드는 동일한

Disassembly of section .text: 

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

상위 4 비트를 수행 이것을 아무리 말아, 상태 필드 표시 섹션을 참조하십시오. 0xE는 항상이 명령어를 실행한다는 것을 의미합니다. 0b0000은 z 플래그가 설정되어있는 경우에만 실행되며, 0b0001은 ne가 z가 클 경우에만 실행됩니다.

ARM에서 ARM 명령 세트로 푸시 한 다음 팔 명령의 알파벳 순 목록을 클릭 한 다음 cmp를 찾습니다. cond 00I10101 rn sbz shifter

위의 cmp 명령에서 우리는 1110 000101010001을 볼 수 있습니다. 그래서 저는 0 비트입니다 15:12는 0 비트이고 27:26은 0이고 24:21은 1010이므로 이것은 cmp입니다. 명령어

위의 비트 19 ~ 16은 0b001입니다. ARM ARM의 시프터 피연산자에 대해서는 rn = rn = 1 (r1)이므로 어드레싱 모드 1 데이터 처리 피연산자를 살펴보고 pdf에서 페이지

우리는 두 번째 피연산자를 단순히 데이터 처리 피연산자 레지스터라고 부르는 레지스터로 알고 페이지 번호는 해당 페이지의 해당 페이지로 이동합니다. 15:12는 rrd 11 : 4는 0이고 3은 3입니다. : 0은 rm입니다. 우리는 cmp 명령에서 15:12이 0이어야한다고 말합니다. 걱정할지라도 cmp는 결과를 레지스터에 저장하지 않으므로 rd는 사용되지 않습니다. rm이 사용되고 r0을 원한다면 0b0000은 3 : 0이됩니다. 또한 cmp 명령 25에서 비트 27:25가 0으로 표시됩니다. 이제 우리는 0을 원한다는 것을 알 수 있습니다.

CMP에 페이지와이 데이터 처리와

- 등록 페이지에서 우리는 전체 그림

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 

추가 기능이 비슷하지만 즉시 사용이 있으므로 지침의 알파 목록에 추가 명령어로 이동합니다. 우리는 이제 cmp로부터이 클래스의 24:21이 opcode임을 알 수 있습니다. 우리는 계속 shifter 피연산자 항목으로 바로 넘어갈 수 있습니다.

이번에는 rd, rn, # immediate를 추가합니다.

그렇게 #immediate

의 페이지를 찾아 및 인코딩은

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) 

이제 흥미로운 부분은, 우리는 26 개 가지 방법을 인코딩 할 수 온다.비트 7 : 0은 즉시이고 비트 11 : 8은 즉각적인 회전을 허용하고, 26은 0x1A입니다. 단순히 0x1A를 하위 8 비트에 넣고 회전을 0으로 설정하면 gnu 어셈블러가 수행 한 것입니다. 아마도 0x8을 하위 8 비트에 넣을 수 있으며 rotate_imm 필드의 1은 ​​1101000 = 1101000 = 오른쪽으로 1 * 2 회전합니다.