2014-09-26 46 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]); 

編輯:通過ARM C內嵌彙編操縱內存中的數組

正如你可以看到我想要操縱通過手臂的內聯彙編數組的一個變量,但我總是得到一個段錯誤。如何在沒有段錯誤的情況下訪問內存?

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)不固定起來|」編譯它時。

順便說一句:我可以「組織」[程序的地址]「內聯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 2014-09-26 12:35:25

+0

如果您有其他問題,請開始一個新的主題 - 一旦答案已經被接受並且被接受,很難對您的編輯進行跟蹤,並且很難正確回答它們。順便說一句 - 使用'adr'的想法是完全錯誤的,並且表明你不知道這條指令是幹什麼的... – 2014-09-26 20:26:32

+0

sry使用adr是一個錯誤,它應該是ldr。 – schwenk 2014-09-28 10:39:33

回答

1

您應該將%[ptrToSmpl]放在方括號內 - 您想要從寄存器中的地址加載/存儲/存儲。

ldr r2,%[ptrToSmpl]被轉換爲ldr r2,rX - 廢話

ldr r2,[%[ptrToSmpl]]ldr r2,[rX] - 正確

而且 - 你應該把R2到被破壞寄存器的列表,如您覆蓋什麼編譯器放那裏。在最後一個(第三個)冒號後面添加「r2」(帶引號)。

+0

我如何增加ptr的值? – schwenk 2014-09-26 18:57:16

+0

只要觀察一下你的編譯器是如何實現的(;寫一個簡單的循環,看看它是如何轉換成彙編語言的(你可以生成像這樣的彙編列表:'arm-none-eabi-objdump --demangle -S file.elf> file.lss ')。如果你想增加地址寄存器_AFTER_的加載(或存儲),你可以這樣做:'ldr r1,[r2],#4'(4顯然是加到r2的數字)。建議你用C語言編寫代碼並檢查程序集 - 然後你會看到編譯器做得如何(並決定不自己編寫代碼),否則你會看到這樣的結構是如何被轉換成程序集的。 – 2014-09-26 20:23:00

1

不要硬編碼程序集應該使用的寄存器。使用%0%1等符號來命名與您傳遞的參數相對應的寄存器。

如果你這樣做是正確的,你不應該在你的情況下使用約束如"memory"