View

300x250

Tab 복사가 안돼서 삐뚤빼뚤 ㅜㅜ

 

Execute unit in ARM

Move instruction - MOV

                mov r0, r0, LSL#1  r0에 저장된 값을 logic shift left로 1칸 옮겨서 r0에 저장하라

                mov pc, r14           r14에 저장된 값을 pc 레지스터에 저장하라

        example

                r0 = 0x80000004

                movs r0, r0, LSL#1

                r0 = 0x00000008, CPSR = nzCv

                movs r0, r0, LSL#1

                r0 = 0x00000010, CPSR = nzcv

                        대부분의 instruction은 (lsl#같은) Barrel shifter를 사용할 수 있다!

 

        instruction 뒤에 붙는 s는 명령어 수행 후 CPSR 플래그를 update하라는 의미

         2bit 이상 Carry out이 발생하는 경우, 가장 마지막으로 나가는 bit가 carry out이 된다.

 

                logic shift 와 arithmetic shift는 left shift는 같지만 right shift에서 차이가 난다.

                        1010 >> 1   ( Unsigned : +10 / signed = -6 )

                        logic : 0101   MSB가 0으로 채워진다. -> unsigned +5

                        arith : 1101   MSB가 signed bit을 copy한다 -> signed -3

 

        arm은 하드웨어적으로 일부의 큰 수를 만들 메커니즘을 가지고 있다.

                32bit Register에 shift operand 12bit중 4bit가 rotation을 위한 bit

                0x12345678은 표현 불가능 - 메모리에 저장하고 불러오기

                0x80000004는 표현 가능 - 레지스터에 저장함

 

Arithmetic Instruction- ADC    Addition with carry

        adc r0, r1, r2    NZCV Flag의 Carry flag가 함께 더해진다.

                r0 = r1 + r2 + C

        long long type의 64bit 두 수를 합하는 연산을 32bit CPU가 처리하기 위해서는 두 번 계산해야한다.

                앞 32bit끼리 adds -> carry flag update -> 뒤 32bit끼리 adc

 

Arithmetic Instruction - SUB     Subtract

        subtract 는 내부적으로 2의 보수의 합으로 표현된다. A - B = A + !B + 1

                sub r0, r1, r2        r0 = r1 - r2 = r1 + !r2 + 1

        

        RSB        Reverse subtract

                rsb r0, r1, r2        r0 = r2 - r1 순서 반대

                int a = -b; 와 같은 상황에서 rsb a, b, #0 ( a = 0 - b ) 처럼 사용된다,

 

        SUBS로 1 - 1을 수행하면

                0x00000001 - 0x00000001 = 0x00000001 + 0xFFFFFFFE+ 0x00000001

                = 0x00000000 with Carry out = 1        NZCV update

                

CLZ - Count Leading Zero

        MSB부터 0의 개수를 세아리며, 1이 나오면 0의 개수를 반환한다.

                r0 = 0000011001...

                clz r1, r0         r1 에 5가 저장됨

 

Logic Instruction 

        AND &

        ORR |

        EOR ^        cost effective 하게 reset하는 용도로 많이 사용 eor r0, r0, r0

        BIC &~        r1에서 r2에 있는 bit들을 지운다. 

 

Compare instruction - CMP

        cmp r0, r1                r0 - r1 을 수행하고, NZCV Flag를 update한다, (cmps가 내장)

                if ( r0 == r1 )        cmp r0, r1

                        r2++                addeq r2, r2, #1

                else

                        r2—;                subne r2, r2, #1

        condition field 를 이용해 조건문을 만들면 neat한 꼴이 된다.

 

Compare instruction - TST, TEQ

        tst r1, r2 == r1 & r2

        teq r1, r2 == r1 ^ r2

        

        destination이 없는 instruction, NZCV flag만 update한다.

 

Branch instruction - B, BL

        program counter에 대한 조작

        B foo                foo 영역으로 pc를 이동

        BL foo        foo 영역으로 pc를 이동 + 다시 돌아올 수 있게 lr에 현 주소 저장

 

        내부적으로 효율을 높이기 위해 파이프라인이 형성되어 있기 때문에, fetch되는 명령어는 현재 execute되는 명령어주소(pc) + 8byte를 읽는다.

        만약에 branch instruction 이 있는 경우 어느 branch로 이동할 지 조건문이 execute되기 전에는 모른다.

                -> fetch한 명령어를 blank instruction으로 취급

                -> 이것도 아까워서 cpu에 branch predicter를 탑재 : 실행되기 전에 어느 branch로 분기될 지 예측하여 fetch

 

Memory instruction

        Single register transfer

                LDR                1 word

                LDRB        1 byte                1 byte를 로드하고 나머지는 다 0으로 채워 저장

                LDRSB        1 signed byte        signed 유지 + 나머지 채우기

                

                        ldr r1, [r2]        r2 (메모리 주소) 에 저장된 값을 r1에 저장

        offset

                ldr r0, [r1, #4]                r1 + 4에 저장된 값을 r0에 저장

        Post indexed

                ldr r0, [r1, #4], #8        r1 + 4에 저장된 값을 r0에 저장하고 r1 += 8

        Pre indexed

                ldr r0, [r1, #16]!                r1 + 16에 저장된 값을 r0에 저장하고 r1 += 4

 

        Multiple register transfer        주로 stack에 register를 저장하기 위해 사용

                LDM                Load multiple data

                STM                Store multiple data

                        수식어로 저장되는 방향을 알려줘야 한다.

                        IA : increment after        DA : decrement after

                        IB : increment before        DB : decrement before

                

                stmia r13!, {r0, r1}        r13에서부터 r0 저장 후 r+4 에 r1을 저장

                stmib r13!, {r0, r1}        r13에서부터 r+4 한 후 r0 저장하고 +=4에 r1 저장

                stmda r13!, {r0, r1}        r13에서부터 r1에 저장 후 r-4에 r0을 저장

                        {r0 - r12}로 한번에 선택도 가능하다.

 

                r13은 stack pointer, 주로 여기를 통해 메모리의 스택영역을 포인팅한

                !는 실행 후 값을 update하는 것을 의미한다.

                거꾸로 내려가더라도 register 순서는 큰 번호가 위로 가도록 유지된다,

                        {r0, r1,r2}로 지정하던 {r2, r1, r0}으로 지정하던 상관 없다.

        

        Stack Operation with LDM, STM

                ARM은 pseudo instruction 을 제공한다. 스택메모리 관리에 좀 더 직관적임. 작동은 위 코드와 같다.

 

                STMFA (= STMIB) full Ascending in Stack

                STMFD (= STMDB) full Descending in stack

                STMEA (= STMIA) Empty Ascending in Stack

                STMED (= STMID) Empty Descending in Stack

 

                push {r0 - r3} == STMFD r13, {r0 - r3}

 

                현재 레지스터 전체를 저장할 때, 메모리가 이미 사용중이라면 스택을 아래로 쌓는다.

                        STMFD r13, {r0, r15}        r13이 가리키는 메모리에서 한 칸 아래부터 아래쪽으로 레지스터 값을 저장한다.

                        ( 현재 r13이 가리키는 메모리가 이미 사용중인 상황일 때 Full descending을 사용 )

                        불러올 때는 r13이 r0이 담겨있는 메모리 주소를 가리키는 상태에서 LDMEA를 사용

                

 

 

// 이 시리즈의 글들은 고려대학교의 Computer System Design 과목 ( COSE321 ) 을 수강하며 제가 공부한 내용입니다.

// 노트필기를 바탕으로 정리하여 올리고 있으므로, 부정확한 정보가 있을 수도 있습니다.

// 추후에 종강을 하면 워터마크를 삽입한 최종노트 PDF를 첨부할 계획입니다.

320x100
Share Link
reply
반응형
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31