Computer Science
탄탄한 기반 실력을 위한
전공과 이론 지식 모음
Today I Learned!
배웠으면 기록을 해야지
TIL 사진
Flutter 사진
Flutter로 모바일까지
거꾸로캠퍼스 코딩랩 Flutter 앱개발 강사
스파르타코딩클럽 즉문즉답 튜터
카카오테크캠퍼스 3기 학습코치
프로필 사진
박성민
임베디드 세계에
발을 들인 박치기 공룡
임베디드 사진
EMBEDDED SYSTEM
임베디드 SW와 HW, 이론부터 실전까지
ALGORITHM
알고리즘 해결 전략 기록
🎓
중앙대학교 소프트웨어학부
텔레칩스 차량용 임베디드 스쿨 3기
애플 개발자 아카데미 1기
깃허브 사진
GitHub
프로젝트 모아보기
Instagram
인스타그램 사진

학부생 CS/컴퓨터 시스템 설계

Computer System Design - 3 : Assembly instruction

sm_amoled 2019. 3. 28. 13:26

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