April 19, 2024

디바이스마트 미디어:

[66호] 원하는 색상으로 제어가 가능한 아두이노 IoT 스마트 무드등 키트 -

2021-06-25

★2021 ICT 융합 프로젝트 공모전 결과 발표! -

2021-05-12

디바이스마트 국내 온라인 유통사 유일 벨로다인 라이다 공급! -

2021-02-16

★총 상금 500만원 /2021 ICT 융합 프로젝트 공모전★ -

2021-01-18

디바이스마트 온라인 매거진 전자책(PDF)이 무료! -

2020-09-29

[61호]음성으로 제어하는 간접등 만들기 -

2020-08-26

디바이스마트 자체제작 코딩키트 ‘코딩 도담도담’ 출시 -

2020-08-10

GGM AC모터 대량등록! -

2020-07-10

[60호]초소형 레이더 MDR, 어떻게 제어하고 활용하나 -

2020-06-30

[60호]NANO 33 IoT보드를 활용한 블루투스 수평계 만들기 -

2020-06-30

라즈베리파이3가 드디어 출시!!! (Now Raspberry Pi 3 is Coming!!) -

2016-02-29

MoonWalker Actuator 판매개시!! -

2015-08-27

디바이스마트 레이저가공, 밀링, 선반, 라우터 등 커스텀서비스 견적요청 방법 설명동영상 입니다. -

2015-06-09

디바이스마트와 인텔®이 함께하는 IoT 경진대회! -

2015-05-19

드디어 adafruit도 디바이스마트에서 쉽고 저렴하게 !! -

2015-03-25

[29호] Intel Edison Review -

2015-03-10

Pololu 공식 Distributor 디바이스마트, Pololu 상품 판매 개시!! -

2015-03-09

[칩센]블루투스 전 제품 10%가격할인!! -

2015-02-02

[Arduino]Uno(R3) 구입시 37종 센서키트 할인이벤트!! -

2015-02-02

[M.A.I]Ahram_ISP_V1.5 60개 한정수량 할인이벤트!! -

2015-02-02

[17호]JK전자와 함께하는 ARM 완전정복(3)-2

jk전자 JK전자와 함/께/하/는 ARM 완전 정복
Ⅱ.ARM Applications – 1부
글 | JK전자

2. 어셈블리어 실습

2.1 ARM Simulator 환경 설정

IAR ARM용 컴파일러는 가격이 그렇게 싸지는 않습니다. 다행히도 www.iar.com 에서 시간 제한(30일), 사이즈 제한(32Kbyte) 버젼을 다운 받아서 사용해 볼 수 있습니다.

2.1.1 IAR Evaluation 버젼 다운로드
- 다운로드 사이트 방문
http://supp.iar.com/Download/SW/?item=EWARM-EVAL
17featureJK034
패키지 사이즈가 약 830MB정도 입니다. 다운 받아서 설치하시기 바랍니다.

다음은 Evaluation 버젼을 다운로드 받기 위한 절차대로 화면을 캡쳐해 놓은 것입니다. 참조하시기 바랍니다.
17featureJK057
반드시 “Code size limited”를 선택하시기 바랍니다. 그렇지 않으면 30일 이후에 더이상 IAR 컴파일러를 사용할 수 없게 됩니다.

(2) IAR Evaluation 버젼 설치

17featureJK054
설치가 완료되면 마지막에 License 를 입력하는 화면이 나옵니다. 여기에서 “Register with IAR System to get an evaluation license”를 선택하시기 바랍니다.

17featureJK055
현재 설치된 제품 중에 라이센스가 없는 제품의 리스트가 나옵니다. 선택을 하고 “다음”으로 진행합니다.

17featureJK056
IAR Evaluation 버젼을 다운받기 위해서 입력했던 Email 주소로 Registeration Confirm 메일이 와있을 것입니다.
Confirm 메일에 있는 Confirm 링크를 클릭하면 “Registration Complete”와 함께 Evaluation License 번호를 알 수가 있습니다. 그 번호를 위의 화면의 빈 칸에 입력하고 나서 “Regiser”버튼을 누르면 잠시 후에 네트워크를 통해서 Evaluation 라이센스 번호를 받게 됩니다. 경우에 따라서 Fail 이라는 메세지가 나올 수도 있습니다. 그때는 “Register”버튼을 다시 한번 클릭해서 재시도해 보시기 바랍니다.
17featureJK058
17featureJK059
모든 설치가 완료된 화면입니다.

2.1.2 ARM Simulator 프로젝트 생성
아래 화면대로 따라서 ARM Simulator 기반의 실습 프로젝트를 생성해 보시기 바랍니다.

(1) Create New Project
17featureJK060

(2) Empty project 생성
17featureJK061

(3) 프로젝트 파일이름 입력 – “arm_simulator”
17featureJK062
17featureJK063

(4) 그룹생성 – “base”, “testcode”그룹 생성
17featureJK064
- “base”그룹 : 2440init_ewarm.s 추가
- “testcode”그룹 : main.c, SegInit.c 추가

(6) 프로젝트 옵션 설정
17featureJK065

(6.1) Target Device 설정
17featureJK066
17featureJK067
Samsung S3C2440A 로 설정합니다.

(7) Processor Mode 설정
17featureJK068
“ARM”모드로 설정합니다.

(8) Scattor Loading 파일 설정
17featureJK069
프로젝트 디렉토리에 “arm_simulator.icf”파일을 선택합니다.

(9) Program Start Entry 설정
17featureJK070
“ __program_start”라고 입력합니다.

(10) 디버깅 정보를 포함하도록 설정합니다.
17featureJK071

(11) Map 파일을 생성하도록 합니다.
17featureJK072

(12) Debugger 정보 설정 : Dirver – Simulator, Run to main은 반드시 설정 해제합니다.
17featureJK073

2.2 Data Processing Instructions

2장에서는 ARM Simulator를 활용한 어셈블리어 실습을 해보도록 하겠습니다. 이 내용들은 ARM Architecture Instruction의 이론 부분을 설명할 때 한번씩 나왔던 내용입니다. 여기서는 이론으로 공부했던 내용들을 실제로 ARM Simulator에서 코드를 작성한 후 컴파일하고 실행해서 결과 값을 직접 확인해 보는데 의미가 있습니다.

R0 = 0×00
R1 = 0×22
R2 = 0×02
R3 = 0×00
R4 = 0×00
17featureJK000

레지스터 값이 위와 같을 때 아래 예제들을 차례대로 수행해 보세요.

(1) AND R0, R0, #0xFF
2440init_ewarm.s 파일에 다음과 같이 입력을 합니다.

SECTION IMAGE_STARTUP:CODE (2)
PUBLIC __program_start
CODE32
__program_start
b ResetHandler
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
ResetHandler
MOV R0, #0×00
MOV R1, #0×22
MOV R2, #0×02
MOV R3, #0×00
MOV R4, #0x00AND R0, R0, #0xFF
ADD R0, R0, #1
ADD R0, R0, R1
LSL R1, R0, #2
SUB R3, R2, R1, LSR R2HandlerFIQ
b .HandlerIRQ
b .HandlerUndef
b .HandlerSWI
b .HandlerDabort
b .HandlerPabort
b .END

- 실행 결과
17featureJK000

(2) ADD R0, R0, #1 ; R0 = R0 + 1 = 0×1
- 실행 결과
17featureJK001

(3) ADD R0, R0, R1 ; R0 = R0 + R1 = 0×01 + 0×22 = 0×23
- 실행 결과
17featureJK002

(4) LSL R1, R0, #2 ; 0×23(100011) LSL #2 = 0x8C(10001100) -> 참고로 왼쪽으로 2번 쉬프트 하면 *4 를 한 것과 같습니다.
- 실행 결과
17featureJK003

(5) SUB R3, R2, R1, LSR R2
- 실행 결과
17featureJK004

R3의 값이 0xFFFFFFDF 로 복잡한 값이 나왔습니다. 왜 이런 결과가 나왔을까요? 우선 R1을 오른쪽으로 2번 쉬프트시키면 0×23이 되고 R2(0×02)에서 R1(0×23)을 빼면 결과 값이 -0×21가 되고 이 값을 2의 보수로 표시하면 0xFFFFFFDF가 됩니다.

0×21 = 00000000000000000000000000100001
-0×21 = 11111111111111111111111111011111 –> 0×21의 2의 보수
참고로 2의 보수를 취하는 방법은 원래의 2진수에서 0->1, 1->0 으로 바꾼 후에 1을 더하면 되겠지요.

2.3 Multiply Instructions

R0 = 0×01
R1 = 0×02
R2 = 0×03
R3 = 0×04
17featureJK005

레지스터 값이 위와 같을 때 아래 예제들을 차례대로 수행해보세요.

(1) MUL R2, R0, R1 ; R2 = R0*R1 = 0×02
2440init_ewarm.s 파일에 다음과 같이 입력을 합니다.

ResetHandler
MOV R0, 0×01
MOV R1, 0×02
MOV R2, 0×03
MOV R3, 0x04MUL R2, R0, R1
MULS R2, R0, R1
MLA R3, R2, R1, R0

- 실행 결과
17featureJK006

(2) MULS R2, R0, R1 ; R2 = R0*R1 = 0×02
MUL 명령과 같은 명령입니다. 하지만 MUL뒤에 “S”가 붙으면 명령어 처리가 끝난 이후에 CPSR의 Flag Field가 연산 결과에 따라서 업데이트가 됩니다.
- 실행 결과
17featureJK006

(3) MLA R3, R2, R1, R0 ; R3 = R2*R1 + R0
참 효율적이네요. 명령어 하나로 곱하기 연산과 더하기 연산을 같이 할 수 있습니다.
- 실행 결과
17featureJK007

2.4 Load/Store Instructions

2.4.1 Pre-index
R0 = 0×31000000
R1 = 0×00
R2 = 0×00
17featureJK008
17featureJK009

(1) LDR R1, [R0] ; R1 2440init_ewarm.s 파일에 다음과 같이 입력을 합니다.

ResetHandler
MOV R0, 0×31000000
MOV R1, 0×0
MOV R2, 0x0LDR R1, [R0] STR R1, [R0, #4] STR R1, [R0, #4]!

- 실행 결과
17featureJK010

(2) STR R1, [R0, #4] ; R1
17featureJK011

(3) STR R1, [R0, #4]! ; R1
- 실행 결과
17featureJK012
17featureJK013

2.4.2 Post-index
R0 = 0×31000000
R1 = 0×00
R2 = 0×04
17featureJK014
17featureJK009

(1) LDR R1, [R0], R2 ; R1

ResetHandler
MOV R0, 0×31000000
MOV R1, 0×0
MOV R2, 0x4LDR R1, [R0], R2
STR R1, [R0], #4

- 실행 결과
17featureJK015

(2) STR R1, [R0], #4 ; R1
- 실행 결과
17featureJK016
17featureJK017

2.5 Load/Store Multiple Instructions

R0 = 0x000A
R4 = 0x000B
R5 = 0x000C
R13 = 0xFFF0
17featureJK035
17featureJK036

(1) STMIA R13!, {R0,R4-R5}

ResetHandler
MOV R0, #0x000A
MOV R4, #0X000B
MOV R5, #0x000C
LDR R13, =0xFFF0STMIA R13!, {R0,R4-R5}

- 실행 결과
17featureJK042
17featureJK036

(2) STMIB R13!, {R0,R4-R5}

ResetHandler
MOV R0, #0x000A
MOV R4, #0X000B
MOV R5, #0x000C
LDR R13, =0xFFF0STMIB R13!, {R0,R4-R5}

- 실행 결과
17featureJK043
17featureJK038

(3) STMDA R13!, {R0,R4-R5}

ResetHandler
MOV R0, #0x000A
MOV R4, #0X000B
MOV R5, #0x000C
LDR R13, =0xFFF0STMDA R13!, {R0,R4-R5}

- 실행 결과
17featureJK042
17featureJK039

(4) STMDB R13!, {R0,R4-R5}

ResetHandler
MOV R0, #0x000A
MOV R4, #0X000B
MOV R5, #0x000C
LDR R13, =0xFFF0STMDB R13!, {R0,R4-R5}

- 실행 결과
17featureJK041
17featureJK040

2.6 Branch Instructions

ResetHandlersubsequent
MOV R0, #1
MOV R1, #2
BL func1
ADD R2, R0, R1func1
MOV R0, #3
MOV R1, #4
BL func2
ADD R2, R0, R1
MOV PC, LRfunc2
MOV R0, #5
MOV R1, #6
ADD R2, R0, R1
MOV PC, LR

위의 예제를 실행하면 R2 레지스터에 “3”이 저장이 되지 않습니다. R2 레지스터에 “3”이 저장이 될 수 있도록 예제를 수정해 보시기 바랍니다. 수정한 예제 코드는 아래와 같습니다.
17featureJK018
서브 함수를 호출 할 경우에는 서브 함수에서 사용하는 레지스터와 LR 레지스터를 반드시 저장한 이후에 사용해야 한다는 것을 알 수 있습니다.

2.7 Status Register Access Instructions
17featureJK019

ResetHandler
MRS R0, CPSR
BIC R0, R0, #0×80 ; 7번 비트를 clear 하면 인터럽트가 활성화 됩니다.
MSR CPSR, R0

- 실행 결과
17featureJK020

2.8 Conditional Execution

지금까지 배운 모든 어셈블리어들을 활용해서 최종적으로 몇가지 예제를 풀어 보도록 하겠습니다. 예제를 구현하는데에는 여러가지 방법들이 많이 있겠지만 가장 최적화된 어셈블리 명령어를 사용하시기 바랍니다.

(1) 1 ~ 10을 더하는 최적화된 어셈블리어로 작성해 보세요.

ResetHandler
MOV R5, #10
MOV R6, #0
loop_sum
ADD R6, R6, R5
SUBS R5, R5, #1
BNE loop_sum ; Not Equal(Z=1)

루프를 사용할 경우에는 거꾸로 도는 것이 효율적입니다.

(2) 2개 변수 사이의 절대값을 구하세요.
- [-2 - 3] 사이의 절대값

ResetHandler
MOV R0, #-2
MOV R1, #3SUBS R0, R0, R1V
RSBMI R0, R0, #0

17featureJK046

“SUBS R0, R0, R1”명령을 실행했을 때의 그림입니다. R0, CPSR의 “N”Flag를 잘 살펴보시기 바랍니다. 참고로 RSBMI 명령어는 CPSR의 “N”Flag가 Set되어 있을 때 뺄셈을 하는데 SUB 명령과는 연산의 방향이 반대로 수행이 되는 명령어입니다. 그러니까 이번 예제에서는 “#0”에서 “R0”를 빼는 것입니다.

- [3 - 1] 사이의 절대값

ResetHandler
MOV R0, #3
MOV R1, #1SUBS R0, R0, R1
RSBMI R0, R0, #0

17featureJK045
“SUBS R0, R0, R1”명령을 실행했을 때의 그림입니다. R0, CPSR의 “N”Flag를 잘 살펴 보시기 바랍니다.

3장에서는 우리가 실제로 실습에 사용할 S3C2440 ARM9 개발보드에 대해서 소개하도록 하겠습니다. ARM Simulator에서는 별다른 설정없이도 어셈블리어 실습을 할 수 있었으나 실제 타겟을 사용할 경우에는 개발보드의 메모리 컨트롤러, 부팅과정 등을 제대로 이해하고 있어야 코드 작성이 가능합니다. 실제 개발보드에서 실습을 하기 전에 S3C2440에 대해서 이론적으로 공부해보도록 하겠습니다.

 

 JK전자와 함께하는 ARM 완전정복(3)-2 에서 계속 됩니다.

Leave A Comment

*