PowerPC ABI zcbm4321@gmail.com 김종화
introduction PowerPC는 약 60개의 기본 명령어존재 많이 사용되는 것은 약 10개 대표적인 명령어 많이 사용되는 것은 약 10개 대표적인 명령어 li – load immediate – 레지스터에 값을 로드한다. stw – 레지스터에서 메모리로 word를 저장한다. lwz – 메모리에서 레지스터로 word를 로드한다.
기본 프로세서의 동작 PowerPC는 크게 두가지 타입으로 레지스터를 나눌수 있다. integer 타입의 r0~r31 floating point 타입의 f0~f31
Example 1 do_add : li r3, 10 li r4, 20 add r5, r4, r3 stw r5, sum(rtoc) blr sum: ds.w 1
데이터 로드하기 lwz rx, EA li rx, num 레지스터에 16bit 값을 채워넣는다. 상위 16비트는 부호 확장으로 사용된다. 즉 15번째 비트가 1이면 나머지 16~31번째 비트는 모두 1이된다.
만약 0x1234가 로드가 되면 r3의 값은 0x00001234가 되고 0xf234가 로드되면 0xfffff234가 된다. li r3, 0x1234 stw r3, my_variable(`bss) bss는 전역데이터가 저장되는 곳이다. 만약 0x1234가 로드가 되면 r3의 값은 0x00001234가 되고 0xf234가 로드되면 0xfffff234가 된다.
전역변수 전역변수는 RAM의 bss섹션에 저장된다. bss는 프로그램 빌드시에 확정되며 메모리에 로드될 때 TOC섹션의 첫번째 엔트리에 그 주소가 있다.
지역변수 지역변수는 스택에 저장된다. 스택포인터는 r1으로 사용한다. lwz r3, my_data(sp) 지역변수는 스택에 저장된다. 스택포인터는 r1으로 사용한다. 일반적인 임시 데이터(return addr)는 스택에 저장되지만 함수 매개변수는 반드시 레지스터에 저장되어야 한다.
데이터의 초기화 bss영역은 실행시간에 setup이 되지만 data 영역은 빌드시 정의된다. fluffy_string: dc.b “Fluffy loves socks” align bss영역은 실행시간에 setup이 되지만 data 영역은 빌드시 정의된다. dc는 define constant 의 약어로서 data 영역으로 정의된다. align 은 다음 데이터를 위한 메모리 정렬이다. data 영역은 메모리 어디서나 위치할 수 있으며 TOC섹션의 참조로 접근이 가능하다. TOC섹션의 위치는 r2에 저장되어 있다.
Example2 entry : lwz r3, fluffy_string(rtoc) blr *************data************* fluffy_string dc.b “Fluffy loves socks” align 020ca238 *dc.l 0x7c22192a | 7c22192a 020ca23c lwz r3, 0x0004(rtoc) | 80620004 020ca240 blr | 4e800020
함수 호출 함수 호출 시 link register를 저장해야한다. my_code: bl my_function1 add r3, r4, r5 blr my_function: mflr r29 your processing code mtlr r29 함수 호출 시 link register를 저장해야한다. 어떤 명령어로 인하여 link register의 값을 잃어버리는 경우가 있다.
정리 sp – 스택 포인터이다. r1으로 사용한다. rtoc – toc 포인터이다. r2로 사용한다. parameters은 일반적으로 r3~r10으로 이용한다. 그리고 return 레지스터는 r3으로 사용된다. 낮은 번호의 레지스터는 휘발성이다. 높은 번호의 레지스터는 비휘발성으로서 오랫동안 저장하고 있다. 예를 들어 LR레지스터를 보통 r29에 저장하거나 r28에 저장한다.
IBM PowerPC 970FX Processor 32bit
64bit
대표적인 명령어
대표적인 명령어
명령어 사용 결과
데이터 타입의 크기
Stack ABI는 표준 함수 호출 과정의 정의에서 다음을 포함한다. 매개변수 전달 레지스터 용도 정의 스택 프레임 레이아웃
Stack
Stack r1은 스택 프레임 포인터이다. 스택 프레임 포인터는 다음과 같은 특징을 반드시 따라야한다. 반드시 8byte의 정렬을 가져야한다. 반드시 스택 프레임의 하단부를 가르켜야한다. 반드시 위에서 아래로 자란다. 스택 프레임의 크기는 16byte의 크기로 나누어 떨어여야한다. 스택 프레임은 stdu의 명령어를 사용하면 자동 업데이트를 한다. back chain은 반드시 이전에 만들어진 스택 프레임을 가르켜야한다. 함수가 호출되면 다음 스택 프레임이 생성이된다.
Stack frame
Table Of Content (TOC) ELF 파일 안에 .toc로 정의되어 있다. example ld r4, 0x1234(r2)
Function Descriptors 64bit 에서만 정의되어 있다. ELF파일 안에 .opd 섹션으로 정의 되어 있다. 어드레스로 함수를 표현하던 것과 달리 함수의 심볼 이름에 디스크립터의 주소가 들어간다.
Object File Format PowerPC 64-bit ELF 포맷은 일반 포맷과 다르다. 새로운 색션이 추가되어 있다.(.glink, .got, .toc, .tocbase, .plt, .opd) 새로운 relocation entries를 가진다.
32-bit software to PowerPC 970FX Computation Mode 함수 포인터 함수 디스크립터를 사용해서 주소를 구해야한다.
TOC programming global symbol은 TOC 포인터을 이용해야한다. high level 언어는 컴파일러에서 변환된다. 다음 예제는 매크로를 사용하여 r4에 global_symbol_name 값의 주소를 TOC pointer를 이용하여 로드하는 것이다.
64bit값을 r4에 로딩하기 PowerPC 970FX에서 GPR에 64bit 값을 로드하기 위해서는 다음과 같은 코드가 필요하다.
Function Prolog and Epilog 어셈블리 언어에서 함수의 prolog와 epilog 코드를 정의해야한다. (32bit PowerPC ABI를 64bit ABI에 포팅 할 경우)
Assembler Data Objects
Assembly Language Function Calls PowerPC 64-bit ELF ABI에서는 함수를 호출할때 다음과 같은 문법을 사용해야한다. dot을 함수 이름 앞에 사용한다. dot이 없을 경우는 toc를 이용하여 주소를 참조해야한다.