"LDM and STM"의 두 판 사이의 차이

TRACE32
이동: 둘러보기, 검색
 
(같은 사용자에 의한 하나의 중간 편집이 숨겨짐)
16번째 줄: 16번째 줄:
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p><span style="font-family: nanum;">아래의 "LDM R1!, {R3,R12}" 명령에서 미리 알아야 할 것은 아래와 같습니다.</span></p>
 
<p><span style="font-family: nanum;">아래의 "LDM R1!, {R3,R12}" 명령에서 미리 알아야 할 것은 아래와 같습니다.</span></p>
<p><span style="font-family: nanum;"><ol>
+
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span>1. R1의 주소에서 값을 차례로 읽어 R3, R12로 복사합니다.</p>
<li>R1의 주소에서 값을 차례로 읽어 R3, R12로 복사합니다.</li>
+
<p style="padding-left: 30px;">2. "LDM"은 "LDMIA"와 동일하니, 매번 읽을때마다 주소값은 증가합니다.</p>
<li>"LDM"은 "LDMIA"와 동일하니, 매번 읽을때마다 주소값은 증가합니다.</li>
+
<p style="padding-left: 30px;">3. "R1" 뒤에 붙어있는 "!"는 연산 결과 후 R1값이 자동으로 변경됨을 의미합니다.</p>
<li>"R1" 뒤에 붙어있는 "!"는 연산 결과 후 R1값이 자동으로 변경됨을 의미합니다.</li>
+
<ol> </ol>
</ol></span></p>
+
<p>&nbsp;</p>
 
<ul>
 
<ul>
 
</ul>
 
</ul>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p><span style="font-family: nanum;">그 결과,</span></p>
 
<p><span style="font-family: nanum;">그 결과,</span></p>
<p><span style="font-family: nanum;"><ol>
+
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span>1. R1의 주소(0x0800_4C48)번지에서 4바이트(0x3D20_3220)를 읽어 R3으로,</p>
<li>R1의 주소(0x0800_4C48)번지에서 4바이트(0x3D20_3220)를 읽어 R3으로,</li>
+
<p style="padding-left: 30px;">2. R1의 주소에서 4증가한 번지(0x0800_4C4C)에서 4바이트(0x4D38_3420)를 읽어 R12로 복사합니다.</p>
<li>R1의 주소에서 4증가한 번지(0x0800_4C4C)에서 4바이트(0x4D38_3420)를 읽어 R12로 복사합니다.</li>
+
<p style="padding-left: 30px;">3. R1은 8바이트(4바이트씩 2번 읽어 왔으므로) 증가한 0x0800_4C50이 됩니다.</p>
<li>R1은 8바이트(4바이트씩 2번 읽어 왔으므로) 증가한 0x0800_4C50이 됩니다.</li>
+
<ol> </ol>
</ol></span></p>
+
<p>&nbsp;</p>
 
<ul>
 
<ul>
 
</ul>
 
</ul>
47번째 줄: 47번째 줄:
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p><span style="font-family: nanum;">아래의 "STMDB R0!, {R2-R5}" 명령에서 미리 알아야 할 것은,</span></p>
 
<p><span style="font-family: nanum;">아래의 "STMDB R0!, {R2-R5}" 명령에서 미리 알아야 할 것은,</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">1. R2 ~ R5의 값을 R0가 가리키는 메모리 번지로 차례로 복사합니다.</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">2. "DB" suffix가 붙었으므로 매번 복사할때 마다 주소값은 0x4씩 감소됩니다.</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">3. "R0" 뒤에 붙어있는 "!"는 연산 결과 후 R0값이 자동으로 변경됨을 의미합니다.</span></p>
 
<ul>
 
<ul>
<li><span style="font-family: nanum;">R2 ~ R5의 값을 R0가 가리키는 메모리 번지로 차례로 복사합니다.</span></li>
 
<li><span style="font-family: nanum;">"DB" suffix가 붙었으므로 매번 복사할때 마다 주소값은 0x4씩 감소됩니다.</span></li>
 
<li><span style="font-family: nanum;">"R0" 뒤에 붙어있는 "!"는 연산 결과 후 R0값이 자동으로 변경됨을 의미합니다.</span></li>
 
 
</ul>
 
</ul>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p><span style="font-family: nanum;">그 결과,</span></p>
 
<p><span style="font-family: nanum;">그 결과,</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">1. R5의 값인 0x55가 R0에서 0x4만큼 감소한 0x2000_1B74 번지로,</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">2. R4의 값인 0x44가 R0에서 0x8만큼 감소한 0x2000_1B70 번지로,</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">3. R3의 값인 0x33가 R0에서 0xC만큼 감소한 0x2000_1B6C 번지로,</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">4. R2의 값인 0x22가 R0에서 0x10만큼 감소한 0x2000_1B68 번지로 차례로 복사됩니다.</span></p>
 +
<p style="padding-left: 30px;"><span style="font-family: nanum;">&nbsp;</span><span style="font-family: nanum;">5. R0값이 (4바이트씩 4번 읽어 왔으므로)0x10만큼 감소한 0x2000_1B68로 변경됩니다.</span></p>
 
<ul>
 
<ul>
<li><span style="font-family: nanum;">R5의 값인 0x55가 R0에서 0x4만큼 감소한 0x2000_1B74 번지로,</span></li>
 
<li><span style="font-family: nanum;">R4의 값인 0x44가 R0에서 0x8만큼 감소한 0x2000_1B70 번지로,</span></li>
 
<li><span style="font-family: nanum;">R3의 값인 0x33가 R0에서 0xC만큼 감소한 0x2000_1B6C 번지로,</span></li>
 
<li><span style="font-family: nanum;">R2의 값인 0x22가 R0에서 0x10만큼 감소한 0x2000_1B68 번지로 차례로 복사됩니다.</span></li>
 
<li><span style="font-family: nanum;">그리고 R0값이 (4바이트씩 4번 읽어 왔으므로)0x10만큼 감소한 0x2000_1B68로 변경됩니다.</span></li>
 
 
</ul>
 
</ul>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
82번째 줄: 82번째 줄:
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p><span style="font-family: nanum;">이와같이 메모리와 레지스터간에 여러개의 데이터를 주고 받는 LDM/STM 명령에 대해 간단히 살펴보았습니다.</span></p>
 
<p><span style="font-family: nanum;">이와같이 메모리와 레지스터간에 여러개의 데이터를 주고 받는 LDM/STM 명령에 대해 간단히 살펴보았습니다.</span></p>
<p><span style="font-family: nanum;">잘못된 점이나 추가 문의사항은 TRACE32@mdstec.com 으로 연락 부탁드립니다.</span></p>
+
<p><span style="font-family: nanum;">잘못된 점이나 추가 문의사항은 TRACE32@hancommds.com 으로 연락 부탁드립니다.</span></p>
 
<p>&nbsp;</p>
 
<p>&nbsp;</p>
 
<p><span style="font-family: nanum;">"<strong><a href="/wiki/index.php/Cortex-M">TRACE32로 바라본 ARM - Cortex-M</a></strong>" 으로 돌아가기</span></p>
 
<p><span style="font-family: nanum;">"<strong><a href="/wiki/index.php/Cortex-M">TRACE32로 바라본 ARM - Cortex-M</a></strong>" 으로 돌아가기</span></p>

2020년 7월 24일 (금) 12:49 기준 최신판

LDR/STR이 메모리와 레지스터간에 데이터를 한번 이동하는 것이라면,

LDM(load multiple register), STM(store multiple register)은 여러개의 데이터를 한번에 이동하는 것입니다.

 

LDM/STM 뒤에는 IA(Increment address After each access) 혹은 DB(Decrement address Before each access)와 같은

 주소 증가/감소에 대한 모드가 표기되는데,

주로 LDM은 IA와, STM은 DB와 쓰이는 것이 일반적입니다.

LDM혹은 STM뒤에 별다른 표기가 없다면, "IA"가 생략되어 있다고 보시면 됩니다.

 

그럼 아래의 예를 통해 LDM/STM의 동작을 살펴보겠습니다.

 

 

LDM : load multiple register

메모리에서 여러개의 데이터를 레지스터로 복사합니다.

바이트(8-bit)/하프워드(16-bit) 복사는 없고 무조건 워드(32-bit) 복사만 존재합니다.

기존에 LDR(load register) 명령을 알고 있는 분이라면 복사 방향이 반대임에 유의하시기 바랍니다.

 

아래의 "LDM R1!, {R3,R12}" 명령에서 미리 알아야 할 것은 아래와 같습니다.

 1. R1의 주소에서 값을 차례로 읽어 R3, R12로 복사합니다.

2. "LDM"은 "LDMIA"와 동일하니, 매번 읽을때마다 주소값은 증가합니다.

3. "R1" 뒤에 붙어있는 "!"는 연산 결과 후 R1값이 자동으로 변경됨을 의미합니다.

 

 

그 결과,

 1. R1의 주소(0x0800_4C48)번지에서 4바이트(0x3D20_3220)를 읽어 R3으로,

2. R1의 주소에서 4증가한 번지(0x0800_4C4C)에서 4바이트(0x4D38_3420)를 읽어 R12로 복사합니다.

3. R1은 8바이트(4바이트씩 2번 읽어 왔으므로) 증가한 0x0800_4C50이 됩니다.

 

아래의 스크린샷을 통해 확인해 보시기 바랍니다.

 

실행 전 :

 

실행 후 :

 

 

STM : store multiple register

여러개의 레지스터값을 메모리로 복사합니다.

바이트(8-bit)/하프워드(16-bit) 복사는 없고 무조건 워드(32-bit) 복사만 존재합니다.

기존에 STR(store register) 명령을 알고 있는 분이라면 복사 방향이 반대임에 유의하시기 바랍니다.

 

아래의 "STMDB R0!, {R2-R5}" 명령에서 미리 알아야 할 것은,

 1. R2 ~ R5의 값을 R0가 가리키는 메모리 번지로 차례로 복사합니다.

 2. "DB" suffix가 붙었으므로 매번 복사할때 마다 주소값은 0x4씩 감소됩니다.

 3. "R0" 뒤에 붙어있는 "!"는 연산 결과 후 R0값이 자동으로 변경됨을 의미합니다.

 

그 결과,

 1. R5의 값인 0x55가 R0에서 0x4만큼 감소한 0x2000_1B74 번지로,

 2. R4의 값인 0x44가 R0에서 0x8만큼 감소한 0x2000_1B70 번지로,

 3. R3의 값인 0x33가 R0에서 0xC만큼 감소한 0x2000_1B6C 번지로,

 4. R2의 값인 0x22가 R0에서 0x10만큼 감소한 0x2000_1B68 번지로 차례로 복사됩니다.

 5. R0값이 (4바이트씩 4번 읽어 왔으므로)0x10만큼 감소한 0x2000_1B68로 변경됩니다.

 

아래의 스크린샷을 통해 확인해 보시기 바랍니다.

 

실행 전 :

 

실행 후 :

 

 

STM은 "DB", LDM은 "IA"와 주로 사용되는 이유

앞에서 address mode에 IA/DB가 있지만,

주로 IA는 LDM과, DB는 STM과 같이 사용된다고 말씀드렸습니다.

 

그 이유는, STM/LDM이 주로 메모리 복사나, 레지스터값의 임시저장(스태킹) 용도로 쓰이다 보니,

아래와 같은 Full Descending stack 방식을 사용하기 때문입니다.

 

 

 

이와같이 메모리와 레지스터간에 여러개의 데이터를 주고 받는 LDM/STM 명령에 대해 간단히 살펴보았습니다.

잘못된 점이나 추가 문의사항은 TRACE32@hancommds.com 으로 연락 부탁드립니다.

 

"TRACE32로 바라본 ARM - Cortex-M" 으로 돌아가기