본문 바로가기

전체 글

(484)
[Arm프로세서] 함수를 호출하기 위한 설계 이번에는 Armv7 아키텍처 관점에서 AAPCS를 SP 레지스터와 LR 레지스터가 어떻게 바뀌는지 기준으로 설명합니다. 하지만 대부분의 시스템 소프트웨어 개발자는 SP와 LR 레지스터를 설정하는 어셈블리 명령어보다 C 언어로 프로그래밍합니다. 그래서 SP와 LR 레지스터를 보면 대부분 낯설게 느낍니다. 그래서 이번 절에서는 함수를 호출하는 예제 코드를 분석하면서 함수를 호출했을 때 SP와 LR 레지스터가 어떻게 바뀌는지 알아보겠습니다. 함수가 호출될 때의 세부 동작 원리 다음과 같은 함수를 작성했다고 가정하겠습니다. 01 int add_func(int x, int y) 02 { 03 int result = x + y; 04 printf("x:%d, y:%d \n", x, y); 05 06 return r..
Armv7 아키텍처에서의 AAPCS 관련 레지스터: SP와 LR 레지스터란 Armv7 아키텍처에서 정의된 범용 레지스터 중 SP(R13) 레지스터와 LR(R14) 레지스터는 AAPCS와 연관된 핵심 레지스터입니다. 먼저 범용 레지스터 가운데 SP, LR 레지스터의 역할을 알아봅시다. SP와 LR 레지스터의 역할 먼저 다음 그림을 보면서 Armv7 아키텍처에서 정의된 레지스터 중 AAPCS와 연관된 레지스터를 알아봅시다. 그림 12.1 Armv7 아키텍처의 레지스터 중 AAPCS와 연관된 레지스터  위 그림은 Armv7 아키텍처에서 동작 모드별로 정의된 레지스터 목록입니다. 그림의 아랫부분에 빗금으로 표시된 부분을 봅시다. 해당 부분의 윗부분에 있는 SP 레지스터를 보겠습니다. 그림의 가장 왼쪽에 SP가 있는데, 같은 행에 각 동작 모드별로 SP_usr, SP_svc, SP_ab..
[Arm프로세서] 메모리 리오더링 예시 이번에는 다음과 같은 예시 명령어를 보면서 메모리 리오더링에 대해 더 자세히 알아봅시다. 그림 17.4 메모리 리오더링의 예 01 ~ 04번째 줄은 모두 스토어 명령어입니다. 01 ~ 04번째 줄 명령어가 실행될 때, X1 레지스터의 값이 0x10000이라고 가정합시다. 또한 명령어가 실행될 때 워드의 단위는 8바이트입니다. 먼저 01번째 줄을 분석하겠습니다. X1 레지스터가 0x10000이니 0x10000 주소에 X0 레지스터의 값(8바이트 크기)을 저장합니다. 01번째 줄이 실행되면 각 바이트는 '1'로 업데이트됩니다. 이는 '1'로 표기된 박스에 해당합니다. 이어서 02번째 줄을 봅시다. 같은 0x10000 주소에 2바이트 사이즈의 데이터를 저장합니다. 여기서 01번째 줄에서 실행된 0x10000 ..
[Arm프로세서] 어드레스 의존성이란? Arm 프로세서 내부에서 성능을 최적화하기 위해 종종 어셈블리 명령어의 순서를 바꿔 실행한다고 설명했습니다. 이런 동작을 수행하기 전에 먼저 각 명령어 간에 의존성이 있는지 체크합니다. 명령어 간 의존성이 있다면 명령어의 순서를 지켜 실행합니다. 다음 어셈블리 명령어를 보면서 어드레스 의존성에 대해 배워 봅시다. 그림 17.2 의존성이 있는 로드(LDR) 명령어의 예시 위 코드는 2개의 로드 명령어로 구성돼 있습니다. 먼저 01번째 줄을 봅시다. X1 레지스터가 0x30000을 담고 있고 0x30000 주소에 0x10000이 있다고 가정합시다. 01번째 줄은 X1 레지스터가 담고 있는 주소에 있는 데이터를 X0 레지스터에 로딩하는 동작입니다. 이어서 02번째 줄은 X0 레지스터의 값에서 8을 더한 결과(..
[Arm프로세서] 메모리 리오더링 소개 대부분 시스템 소프트웨어 개발자는 C 언어로 프로그래밍합니다. C 언어로 작성된 코드는 컴파일러에 의해 기계어로 변환되는데, 이 과정에서 컴파일러는 성능을 최적화하기 위해 코드를 나름대로 재해석합니다. 컴파일러에 의해 최적화된 코드를 보면 "참 컴파일러는 똑똑하구나, 어떻게 코드를 알아서 생성했을까!"란 생각이 듭니다. C 코드를 컴파일할 때 컴파일러 최적화 옵션을 적용하는데, 최적화 레벨이 높을수록 컴파일러는 더 높은 수준의 최적화를 수행합니다. 하지만 컴파일러는 프로그래머가 작성한 코드를 최적화하는 과정에서 종종 사고를 치기도 합니다. 코드를 최적화하다 보니 선을 넘어 프로그래머가 의도하지 않은 코드를 생성하기 때문입니다. 예를 들어, 함수를 인라인으로 처리하면서 심벌이 제거되기도 합니다. 컴파일러가..
[Arm프로세서] Armv8:메모리 맵과 메모리 모델 지금까지 Arm 아키텍처에서 정의된 노멀 메모리 타입과 디바이스 메모리 타입을 알아봤습니다. 이어서 메모리 맵을 보면서 노멀 메모리 타입과 디바이스 메모리 타입의 특징을 자세히 알아봅시다. [정보] 메모리 맵이란? 실전 프로젝트를 진행하면 메모리 맵이란 용어를 자주 듣습니다. 메모리 맵은 무엇일까요? 프로그램에 의해 실행되는 프로세스 입장에서 바라 본 메모리 레이아웃입니다. 지도를 보면 일정한 규칙(시/도)에 따라 구획이 나눠져 있듯이 메모리 영역을 속성별로 분류한 일종의 메모리 지도가 메모리 맵입니다. 메모리 맵의 구조도 알아보기 메모리 맵은 데이터 영역, 코드와 같은 속성으로 마킹된 다양한 영역으로 구성돼 있습니다. 다음 그림을 보면서 메모리 맵에 대해 더 자세히 알아봅시다. 출처: Learn the..
[Arm프로세서] Armv8: 디바이스 메모리란? 이어서 디바이스 메모리를 알아봅시다. 메모리 맵을 보면 다양한 페리페럴 디바이스의 세부 정보와 함께 레지스터를 볼 수 있습니다. 이를 Memory-Mapped I/O 혹은 디바이스 메모리라고 합니다. 디바이스 메모리 타입은 노멀 메모리 타입과 어떤 차이점이 있을까요? Arm 프로세서 입장에서 노멀 메모리로 마킹된 데이터는 메모리에 접근하는 명령어의 순서를 바꾸는 메모리 리오더링 기법이 적용됩니다. 하지만 디바이스 메모리인 경우는 다릅니다. 디바이스 메모리로 마킹된 데이터에 액세스할 때 메모리 리오더링이 적용되면 프로그래머가 예상하지 못한 오동작이 발생할 수 있습니다. 그래서 디바이스 메모리로 마킹된 데이터는 명령어를 순차적으로 실행해야 합니다. 디바이스 메모리는 페리페럴을 제어하는 용도로 사용되므로 명령..
[Arm프로세서] Armv8: 노멀 메모리 타입이란 명령어를 실행하거나 명령어 실행 과정에서 처리되는 데이터나 코드는 노멀 메모리 타입으로 처리됩니다. 대부분의 소프트웨어 개발자가 입력한 코드는 노멀로 마킹된 메모리 영역에 로딩된다고 볼 수 있습니다. Arm 프로세서는 노멀 메모리로 마킹된 영역의 데이터를 처리하기 위해 캐싱 기법을 적용합니다. CPU는 노멀 메모리로 마킹된 메모리 영역에 대해 다음과 같은 기법을 적용해 최적화를 수행합니다. l 머지 액세스 l 스페큘레이션(speculation) l 리오더링 액세스 노멀 메모리를 처리하는 과정에서 적용되는 다양한 기법을 소개합니다. 머지 액세스 메모리 공간에 여러 번 접근하거나 연속된 메모리 공간에 접근하는 2개 이상의 명령어를 한 번에 처리하는 동작을 머지 액세스(merge access)라고 합니다. C..