2014-09-26 4 views
1
int smplSize = 48; 
int Smpl[48]; 

for(int i = 0; i < smplSize; i++) Smpl[i] = 0x0; 
Smpl[smplSize-1] = 0x1; 

int *ptrToSmpl = &Smpl[0]; 

printf("Sample @%p of Size %i :\n",(void*)ptrToSmpl,smplSize); 

asm volatile(

      "@ ------------------------------------------------- \n" 
      "@ Invert the sample \n" 
      "@ ------------------------------------------------- \n" 

      //"0:    \n" 
      "ldr r2,[r3] \n" 
      //"cmp r2,#0x1   \n" 
      //"bne 1f    \n" 
      "add r2,#0x1  \n" 

      //"add r2,#0x1   \n" 
      "str r2,[r3]  \n" 

      //"ldr r1, .0    \n" 
      //"bx r1    \n" 
      //"1:    \n" 


      : 
      : "r" (ptrToSmpl) 
      : "r3", "memory" 

      ); 

printf("Sample[0] = %i" , Smpl[0]); 

편집 :팔 C 인라인 어셈블러를 통해 메모리에 배열을 조작

당신은 내가 팔에 인라인 어셈블러를 통해 배열의 변수를 조작 할 볼 수 있습니다,하지만 난 항상 세그먼트 폴트를 얻을 수있다. segfault없이 메모리에 어떻게 액세스 할 수 있습니까?

printf("Hello inline asmTest start!\n\n"); 

int smplSize = 48; 
int Smpl[48]; 

for(int i = 0; i < smplSize; i++) Smpl[i] = 0x0; 
Smpl[smplSize-1] = 0x1; 

int *ptrToSmpl = &Smpl[0]; 

printf("Sample @%p of Size %i :\n",(void*)ptrToSmpl,smplSize); 

asm volatile(

      "@ ------------------------------------------------- \n" 
      "@ Invert the sample \n" 
      "@ ------------------------------------------------- \n" 

      //"0:    \n" 

      "ldr r2,%[ptrToSmpl] \n" 
      //"cmp r2,#0x1   \n" 
      //"bne 1f    \n" 
      "add r2,#0x1  \n" 

      //"add r2,#0x1   \n" 
      "str r2,%[ptrToSmpl]  \n" 

      //"ldr r1, .0    \n" 
      //"bx r1    \n" 
      //"1:    \n" 


      : 
      : [ptrToSmpl]"r" (ptrToSmpl) 
      : 

      ); 

printf("Sample[0] = %i" , Smpl[0]); 

좋아, 내가 그렇게했지만 지금은 얻을 "/tmp/cczQDyiw.s|72|Error : internal_relocation (유형 : OFFSET_IMM가)를 고정하지를 |" 그것을 컴파일 할 때.

BTW : "org [Adress of the programm]"인라인 asm 코드를 사용할 수 있습니까?

printf("Hello inline asmTest start!\n\n"); 

int smplSize = 48; 
int Smpl[48]; 

for(int i = 0; i < smplSize; i++) Smpl[i] = 0x0; 
Smpl[smplSize-1] = 0x1; 

int *ptrToSmpl = &Smpl[0]; 

printf("Sample @%p of Size %i :\n",(void*)ptrToSmpl,smplSize); 

asm volatile(

      "@ ------------------------------------------------- \n" 
      "@ Invert the sample \n" 
      "@ ------------------------------------------------- \n" 

      "init:    \n" 
      "ldr r0,%[ptrToSmpl] \n" 

      "loop :     \n" 
      "ldr r4,[r0]  \n" 
      "cmp r4,#0x0   \n" 
      "bne end    \n" 

      "add r4,#0x1   \n" 
      "str r4,[r0]  \n" 

      "add r0,#0x1  \n" 


      "b loop    \n" 
      "end:    \n" 


      : 
      : [ptrToSmpl]"r" (ptrToSmpl) 
      : "r0" , "r4", "memory" 

      ); 

printf("Sample[0] = %i" , Smpl[0]); 

편집 2 : 당신은 내가 생각하는 adressing에서이 문제를 여전히 프로그래머 위에서 볼 수 있듯이

. 오류 메시지는 다음과 같습니다. "/tmp/ccE69oZd.s|75|Error : 정의되지 않은 기호 r6이 즉각적인 값으로 사용되었습니다." 어디에도 r6이 없습니다.

+2

어떻게 ptrToSmpl이 r3에서 끝나는 지 확인 하시겠습니까? http://goo.gl/1aJ5t8 – auselen

+0

다른 질문이있는 경우 새 글을 작성하십시오. 수정 사항을 따르기가 어려우며 일단 답변이 이미 제공되고 승인되면 제대로 답변하기 어렵습니다. BTW -'adr'을 사용하는 당신의 아이디어는 완전히 잘못되어이 명령이 무엇을하는지 모른다는 것을 보여줍니다 ... –

+0

adr을 사용하는 sry는 ldr이어야하는 실수였습니다. – schwenk

답변

1

대괄호 안에 %[ptrToSmpl]을 넣어야합니다. 레지스터에있는 주소에서로드/저장하려고합니다.

ldr r2,%[ptrToSmpl]ldr r2,rX로 번역됩니다 - 말도

ldr r2,[%[ptrToSmpl]]ldr r2,[rX] - 올바른

을 또한 - 당신이 거기에두고 어떤 컴파일러 덮어대로,의 Clobbered 레지스터의 목록에 R2를 넣어해야합니다. 마지막 (세 번째) 콜론 다음에 "r2"(따옴표 포함)를 추가하십시오.

+0

어떻게 ptr 값을 증가시킬 수 있습니까? – schwenk

+0

간단한 루프를 작성하여 어셈블리로 변환하는 방법을 살펴보십시오 (이 'arm-none-eabi-objdump --demangle -S file.elf> file.lss와 같은 어셈블리 목록을 생성 할 수 있습니다. '). 주소 레지스터 _AFTER_를로드 (또는 저장) 할 때 'ldr r1, [r2], # 4' (4는 분명히 r2에 추가 된 숫자)와 같이 수행합니다. C로 코드를 작성하고 어셈블리를 검사 할 것을 제안합니다. 그러면 컴파일러가 얼마나 잘 작동하는지 (그리고 직접 작성하지 않기로 결정할 때) 또는 어셈블리가 어셈블리로 변환되는 방법을 확인할 수 있습니다. –

1

어셈블리에서 사용할 레지스터를 하드 코딩하지 마십시오. 전달중인 매개 변수에 해당하는 레지스터의 이름을 지정하려면 %0, %1 등 표기법을 사용하십시오.

정확하게 입력하면 "memory"과 같은 제약 조건을 사용할 필요가 없습니다.