2013-05-19 2 views
0

최근에 내 대학에서 ARM 어셈블리 과정이 시작되었거나 할당이 C 코드에서 호출 된 NxM * MxP 행렬 곱셈 프로그램을 만드는 것입니다.ARM 어셈블리의 행렬 곱셈

이제 저는 도박꾼에 대한 지식이 상당히 제한되었지만 배울 의향이 있습니다. 제가 알고 싶은 것은 이것입니다 :

  1. C에서 ASM으로 2D 배열을 읽거나 전달하는 방법은 무엇입니까?
  2. 2D 배열을 다시 C로 출력하는 방법은 무엇입니까?

나는 나머지 부분을 혼자서 생각할 수 있다고 생각하지만,이 두 가지 사항은 어려운 것으로 알고 있습니다.

나는이 코드에 대해 우분투에서 qemu에 ARM 어셈블리를 사용하고 있습니다. 특정 장치에서는 작동하지 않습니다.

+0

http://www.arm.com/products/processors/technologies/neon.php –

답변

2

C 배열은 단지 포인터 일 뿐이므로 C 배열을 assemply 함수의 인수로 전달하면 배열의 내용 인 메모리 영역에 대한 포인터가 생깁니다.

인수를 검색하는 경우 사용하는 호출 규칙에 따라 다릅니다.

제 4 개 개의 레지스터 R0-R3 (A1 ~ A4)이 서브 루틴으로 인수 값을 전달하고, 함수로부터 결과 값을 리턴하는 데 사용된다 아암 EABI 그 규정하고있다. 루틴 내에서 중간 값을 유지하는데도 사용할 수 있습니다 (일반적으로 서브 루틴 호출간에 만).

간단한 함수의 경우 함수 서명에 따라 r0에서 r4까지 배열에 대한 포인터를 찾아야합니다. 그렇지 않으면 스택에서 찾을 수 있습니다. ABI가 무엇인지 정확히 알아내는 좋은 방법은 어셈블리 함수를 호출하는 C 코드의 오브젝트 파일을 디스 어셈블하고 어셈블리 함수를 호출하기 전에 수행 할 작업을 확인하는 것입니다. 그런 다음

extern int myasmfunc(int *); 

static int array[] = { 0, 1, 2 }; 

int mycfunc() 
{ 
    return myasmfunc(array); 
} 

로 컴파일 :

예를 들어, 리눅스에, 당신은라는 파일에 다음 C 코드 testasm.c을 컴파일 할 수

arm-linux-gnueabi-gcc -c testasm.c 

그리고 마지막으로 해체를 얻을 :

arm-linux-gnueabi-objdump -S testasm.o 

결과 :

testasm.o:  file format elf32-littlearm 


Disassembly of section .text: 

00000000 <mycfunc>: 
    0: e92d4800 push {fp, lr} 
    4: e28db004 add fp, sp, #4 
    8: e59f000c ldr r0, [pc, #12] ; 1c <mycfunc+0x1c> 
    c: ebfffffe bl 0 <myasmfunc> 
    10: e1a03000 mov r3, r0 
    14: e1a00003 mov r0, r3 
    18: e8bd8800 pop {fp, pc} 
    1c: 00000000 andeq r0, r0, r0 

매개 변수를 r0에 넣으면 단일 매개 변수화 된 함수 myasmfunc이 호출됨을 알 수 있습니다. ldr r0, [pc, #12]의 의미는 "pc+12에있는 메모리 주소의 내용으로 r0에로드"입니다. 여기서 배열에 대한 포인터가 저장됩니다.

0

Guillaumes가 대답을 많이 했음에도 불구하고 나는 약간의 코드로 내 자신의 질문에 대답하려고 생각했습니다.

내가 한 일은 1D 배열을 만들고 크기와 함께 asm에 전달하는 것입니다.

int *p; 
    scanf("%d", &h1); 
    scanf("%d", &w1); 
    int* A =(int *) malloc (sizeof(int) * (w1 * h1)); 
    p=A; 
    int i; 
    int j; 
    for(i=0;i<(w1*h1);i++) 
    { 
     scanf("%d", p++); 
    } 

상기되는 것을 I는 다른 배열을 동일한 (malloc) 방식으로 할당하고 aswell을 따라 통과. 그런 다음 어셈블리 코드의 적절한 주소에 필요한 int 값을 저장하고 배열 요소의 주소가 변경되지 않기 때문에 결과를 출력하기 위해 동일한 배열을 사용했습니다.