LDR r0, [r1]
STR r0, [r1]
LDRB r0, [r1] ;r0[7:0] = mem8[r1]
COPY ADR r1 TABLE1 ;r1에는 TABLE1의 주소가 들어감
ADR r2 TABLE2 ;r2에는 TABLE2의 주소가 들어감
LOOP LDR r0, [r1] ;r1이 가리키는 값이 r0로 들어감
STR r0, [r2] ;r0의 값이 r2가 가리키는 메모리로 들어감
TABLE1 ... ;data의 source
TABLE2 ... ;data의 목적지
COPY LDR r1 VALUE1 ;r1에는 VALUE1가 가리키는 값이 들어감(r1 = &0000a000 )
LDR r2 VALUE2 ;r2에는 VALUE2가 가리키는 값이 들어감(r2 = &0000a008 )
MOV r3, #7 ;r3에 7을 넣음
STR r3, [r1] ;mem32[&0000a000] = r3 = 7
LDR r0, [r1] ;r0 = mem32[&0000a000] = 7
STR r0, [r2] ;mem32[&0000a008] = r0 = 7
VALUE1 DCD &0000a000 ;VALUE1 = &0000a000
VALUE2 DCD &0000a008 ;VALUE2 = &0000a008
data1 DCD 1,5,20 ;memory에 3words 할당 그 안에 1,5,20을 넣어
data2 DCD mem06 ;memory에 1word 할당 그 안에 label인 mem06의 주소를 넣어
data3 DCD glb + 4 ;memory에 1word 할당 그 안에 4 + glb의 값을 넣어
COPY LDR r1 VALUE1 ;r1에는 VALUE1가 가리키는 값이 들어감(r1 = &0000a000 )
LDR r2 VALUE2 ;r2에는 VALUE2가 가리키는 값이 들어감(r2 = &0000a008 )
MOV r3, #7 ;r3에 7을 넣음
STR r3, [r1] ;mem32[&0000a000] = r3 = 7
LDR r0, [r1] ;r0 = mem32[&0000a000] = 7
STR r0, [r2] ;mem32[&0000a008] = r0 = 7
;주소 변환(다음 word로)
ADD r1, r1, #4 ; r1 = r1(&a000) + 4 = &a004
ADD r2, r2, #4 ; r2 = r2(&a008) + 4 = &a00c
;다음 주소에 r0값을 넣음
LDR r0, [r1] ;r0 = mem32[&0000a004] = 7
STR r0, [r2] ;mem32[&0000a00c] = r0 = 7 (copy)
VALUE1 DCD &a000, &a004 ;source of data
VALUE2 DCD &a008, &a00c ;destination
✮ Ex. Pre-indexed addressing
COPY LDR r1 VALUE1 ;r1에는 VALUE1가 가리키는 값이 들어감(r1 = &0000a000 )
LDR r2 VALUE2 ;r2에는 VALUE2가 가리키는 값이 들어감(r2 = &0000a008 )
MOV r3, #7 ;r3에 7을 넣음
STR r3, [r1] ;mem32[&0000a000] = r3 = 7
LDR r0, [r1] ;r0 = mem32[&0000a000] = 7
STR r0, [r2] ;mem32[&0000a008] = r0 = 7
;다음 주소에 r0값을 넣음
LDR r0, [r1, #4] ;r0 = mem32[&0000a004] = 7
STR r0, [r2, #4] ;mem32[&0000a00c] = r0 = 7 (copy)
VALUE1 DCD &a000, &a004 ;source of data
VALUE2 DCD &a008, &a00c ;destination
✮ Ex. Post-indexed addressing
COPY LDR r1 VALUE1 ;r1에는 VALUE1가 가리키는 값이 들어감(r1 = &0000a000 )
LDR r2 VALUE2 ;r2에는 VALUE2가 가리키는 값이 들어감(r2 = &0000a008 )
MOV r3, #7 ;r3에 7을 넣음
STR r3, [r1] ;mem32[&0000a000] = r3 = 7
LDR r0, [r1], #4 ;r0 = mem32[&0000a000] = 7 ;r1 := r1 + 4
STR r0, [r2], #4 ;mem32[&0000a008] = r0 = 7 ;r2 := r2 + 4
;다음 주소에 r0값을 넣음
LDR r0, [r1] ;r0 = mem32[&0000a004] = 7
STR r0, [r2] ;mem32[&0000a00c] = r0 = 7 (copy)
VALUE1 DCD &a000, &a004 ;source of data
VALUE2 DCD &a008, &a00c ;destination
LDMIA r1 {r0, r2, r5} ;r0 := mem32[r1]
;r2 := mem32[r1 + 4]
;r5 := mem32[r1 + 8]
;r1에 mem주소가 있음
;r1에 ! 안 붙이면 r1이 변하지 않음(!는 auto-indexing 표시)
✮ 뽀인트
LDMIA r0! {r2 - r9} ;r0는 명령이 끝난 후 32만큼 증가
STMIA r1 {r2 - r9} ;auto-indexing X -> r1은 변하지 않음
STMFD r13! {r2 - r9} ;STMFD = STMDB ;regs를 stack에 저장 (r13 := r13 - 32)
STMIA r0! {r2 - r9} ;STMIA = STMEA ;regs의 block을 복사 (r0 := r0 + 32)
LDMDB r1, {r2 - r9} ;LDMDB = LDMEA ;block of data를 memory에서 restore(auto-indexing X)
LDMFD r13!, {r2 - r9} ;LDMFD = LDMIA ;stack restore(auto-indexing)
MOV r0, #0 ;counter 초기화
LOOP ADD r0, #1 ;loop counter 증가
CMP r0, #10 ;r0가 10이 아니면
BNE LOOP ;LOOP로 branch
CMP r0, #5 ;r0와 5 비교
BEQ BYPASS ;if(r0 != 5){
ADD r1, r1, r0 ;r1 := r1 + r0 - r2
SUB r1, r1, r2 ;}
BYPASS
-EX2
CMP r0, #5 ;r0와 5 비교
;if(r0 != 5){
ADDNE r1, r1, r0 ;r1 := r1 + r0 - r2
SUBNE r1, r1, r2 ;}
-EX3
CMP r0, r1 ;a==b인지 확인
CMPEQ r2, r3 ;a==b이면 c==d인지 확인
ADDEQ r4, r4, #1 ;a==b & c==d이면 e++
BL SUBR ;SUBR로 branch
...
SUBR ...
MOV pc, r14 ;원래 pc로 return
BL SUB1 ;SUBR로 branch
...
SUB1 ...
STMFD r13!, {r0-r2, r14} ;subroutine1의 work와 link register를 stack에 저장
BL SUB2 ;nested subroutine2로 branch
...
LDMFD r13!, {r0-r2, pc} ;subroutine1을 작업하기 전으로 복귀
SUB2 ...
MOV pc, r14 ;다시 sub1으로 복귀 (BL 다음 명령어로)
BL SUBR ;SUBR로 branch
...
SWI_WriterC EQU &0
SWI_Exit EQU &11 ;EQU : 변수에 값을 할당
SWI SWI_WriterC ; = SWI &0 : output r0[7:0]
SWI SWI_Exit ;= SWI &11 : user program에서 moniter로 제어권을 넘김
; 디스플레이에 어떤 값을 출력하는 ARM 명령어
BL JTAB ;SUBR로 branch
...
JTAB CMP r0, #0 ;r0가 0이면 SUB0 선택
BEQ SUB0
CMP r0, #1 ;r0가 1이면 SUB1 선택
BEQ SUB1
CMP r0, #2 ;r0가 2이면 SUB2 선택
BEQ SUB2
BL JTAB ;SUBR로 branch
...
JTAB ADR r1, SUBTAB ;r1이 SUBTAB의 주소를 가리키게 함
CMP r0, #SUBTAB ;r0(원하는 subroutine 번호)와 SUBTAB의 개수 비교
LDRLS pc, [r1, r0, LSL #2] ;r0가 SUBTAB개수보다 작으면 pc에다가 r1+4*r0를 넣어 -> 원하는 subroutine 실행
B ERROR ;r0가 SUBTAB의 개수보다 많으면 ERROR
SUBTAB DCD SUB0 ;subroutine entry point의 table ;r0=0 일때의 subroutine entry point
DCD SUB1 ;r0=1 일때의 subroutine entry point
DCD SUB2 ;r0=2 일때의 subroutine entry point
AREA HelloW, CODE, READONLY ;code area 선언
SWI_WriteC EQU &0 ;r0에 있는 character를 출력(system call)
SWI_Exit EQU &11 ;EQU : 변수에 값을 할당 ;finish program (system call)
ENTRY
START ADR r1, TEXT ;r1에 문자열이 저장되어 있는 메모리의 주소를 넣어
LOOP LDRB r0, [r1], #1 ;byte 단위로 data 읽어와(byte 단위라서 #1를 주소에 더해줌)
CMP r0, #0 ;r0가 0인지 확인 (문자열이 끝났는지 확인하는 코드)
SWINE SWI_WriteC ;r0가 문자열의 끝이 아니면 문자열 print
BNE LOOP ;r0가 문자열의 끝이 아니면 다시 LOOP으로 돌아가서 data 읽어와
SWI SWI_Exit ;r0에 0이 들어가 있으면 시스템 종료
TEXT = "Hello ARM World", &0a, &0d, 0 ;0은 string의 끝을 의미
AREA BlkCpy, CODE, READONLY ;code area 선언
SWI_WriteC EQU &0 ;r0에 있는 character를 출력(system call)
SWI_Exit EQU &11 ;EQU : 변수에 값을 할당 ;finish program (system call)
ENTRY
START ADR r1, TABLE1 ;r1에 TABLE1이 시작되는 주소를 넣어
ADR r2, TABLE2 ;r2에 TABLE2이 시작되는 주소를 넣어
ADR r3, T1END ;r3에 T1END이 시작되는 주소를 넣어
LOOP1 LDR r0, [r1], #4 ;TABLE1의 data를 읽어와(한번에 4개의 character -> 맨 처음엔 This 읽어옴)
STR r0, [r2], #4 ;TABLE2에 TABLE1에서 읽어온 4개의 문자를 저장
CMP r1, r3 ;문자열이 끝났는지 아닌지 확인
BLT LOOP1 ;TABLE1의 문자열을 다 안 읽어왔으면 block copy 더 진행
ADR r1, TABLE2 ;TABLE1의 문자열을 TABLE2로 다 복사했으면 r1이 TABLE2의 주소를 가리키게 함
LOOP2 LDRB r0, [r1], #1 ;byte 단위로 data 읽어와(byte 단위라서 #1를 주소에 더해줌)
CMP r0, #0 ;r0가 0인지 확인 (문자열이 끝났는지 확인하는 코드)
SWINE SWI_WriteC ;r0가 문자열의 끝이 아니면 문자열 print
BNE LOOP2 ;r0가 문자열의 끝이 아니면 다시 LOOP2으로 돌아가서 data 읽어와
SWI SWI_Exit ;r0에 0이 들어가 있으면 시스템 종료
TABLE1 = "This is the right string!", &0a, &0d, 0 ;0은 string의 끝을 의미
T1END
ALIGN ;word align을 보장하는 코드
TABLE2 = "This is the wrong string!", &0a, &0d, 0 ;0은 string의 끝을 의미
;프로그램이 끝났을 때 wrong이 right으로 바껴야 제대로 코드가 실행된거임
END