겁먹지말자. 까보면 진짜 명령어 한줄 짜리들이라 C보다 훨씬 심플들하다.
어셈을 읽을 줄만 알면 된다
. 진짜 처음부터 짜보는 일은 (거의)없음.명령어 구조로 되어있는 프로그래밍 언어.
OPcode<cond> Rd Rm Rn
- OPcode<>: 명령어 <옵션>
- Rd: 목적지 레지스터. 결과 값자리. R0~15만 올 수 있음.
- Rm: R0~15만 올 수 있음.
- Rn: 여러 값들을 올릴 수 있음
예시) MOV R0,R1,R2
덧붙임 명령어
[]
: syntax. 포인터 비슷!
: Write back 연산자. 업데이트 명령어S
: 계산 후 CPSR에 SPSR을 넣어 복구아래는 Instructions(명령어) 이다.
B _printf
: Printf로 점프BL _printf
: LR(R14, 링크레지스터)에 주소 백업 후 점프BX _printf
: Mode(ARM <-> THUMB) 변경 후 점프BLX _printf
: L(주소백업)도하고 X(모드변경)도 한 후 점프BNE _printf
: PC와 값이 다르다면(if Not Equals) 점프MOV Rd, Rm
: Rm을 Rd로 옮겨라. 복사. (Rd = Rm)MVN Rd, Rm
: Rm의 Negative값을 Rd로 복사ADD Rd, Rm, Rn
: Rm + Rn = RdSUB Rd, Rm, Rn
: Rm - Rn = RdRSB Rd, Rm, Rn
: Reverse SUB. Rn - Rm = RdAND Rd, Rm, Rn
: And 연산BIC Rd, Rm, Rn
: 비트클리어. Rd = Rm & ~RnCMP Rm Rn
: Rm이 더큰가? (결과는 CPSR에 업데이트됨)LDR Rd, Rm
: Rm을 Rd에 로드(저장)STR Rd, Rm
: Rm를 Rn에 복사(저장)LDR Rd, [Rm, offset]
LDR, Rd, [Rn, offset]!
LDR Rd, [Rm], offset
LDM{addr_mode} Rn, Rs
, STM{addr_mode} Rn, Rs
STMDA
동작구조와 동일하다LDR Rd, Label
: Rd = *(PC + offset)ADR Rd, Label
: Rd = Label주소SWP Rd Rm [Rn]
MRS Rd CPSR
MSR CPSR Rm
SWI 0x11
: SWI에서 0x11 case 호출data1 DCD 1,5,20 ; data1은 1,5,20을 이은 형태로 word형으로 3개의 메모리 새로 할당
data2 DCD mem06 + 4 ; data2 는 라벨 mem6에 4를 더한 형태로 1개의 word형으로 메모리 새로 할당
어셈은 두가지로 나뉜다 (ADS, GNU)
어셈에서 코드란?
Directives + Label + Instruction + Comment
OhHellNo 코드 예시
CODE32
AREA OhHellNo CODE, READONLY
ENTRY
BEGIN @ LABEL
ADR r0, THUMB
BX r0
THUMB @ LABEL
ADR r1,
LOOP @ LABEL
LDRB r0, [r1], #1
CMP r0, #0
BLNE print_ch
BNE LOOP
B EXIT
TEXT = "Oh Hell No..", 0 @ LABEL
END
Dircectives: 지시어
CODE 32/16: ARM/Thumb 모드
AREA: 코드묶음. 링커가 다루는 최소 단위 모음.
예시: AREA OhHellNo CODE, READONLY
ENTRY: 코드 시작지점 (PC 시작점)
LABELS: 레이블. 사용자 지정 심볼. 그저 이름표.
END: 코드의 끝.
EXPORT, IMPORT 지시어