亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1789 | 回復(fù): 0
打印 上一主題 下一主題

gnu C語言中嵌入式匯編 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-12-23 03:03 |只看該作者 |倒序?yàn)g覽
Andrew Huang <bluedrum@163.com> 轉(zhuǎn)載請注明作者及出處

一.嵌入式匯編關(guān)健字 asm
  
   在所有C程序中,嵌入式匯編的寫法有asm{} asm(), __asm__ __volatile__ ("");其中asm 和 __asm 含義是一樣的.
  而ARM的C編譯器中,主流是兩大類,一類ARM公司出品的ARMCC,另一類用得更廣的是gnu 的匯編,兩者嵌入式匯編語法主和格式,有著很多細(xì)節(jié)微差別,這里主要討論 Gnu格式的.

  ARM的嵌入式匯編是沒有引號,用花括號包括進(jìn)來,如下格式,多行之間直接采用回車分隔,語法采用ARM匯編格式.后文將不討論
     asm { 
        nop 
       mvn r0,#0
    }
 
  __voliatie 主要主要讓編譯不要對讀寫進(jìn)行優(yōu)化.

  GNU 嵌入式匯編格式,用gcc編譯的匯編必須滿足如下格式
  •      一般以  __asm __volatile打頭,用()包括起來,
  • 每句語句用""包括起來  
  • 多語句之間用 \n或\nt分隔
  • 專用寄存器用%%的打頭表示,
以下就是一個簡單的嵌入式匯編格式
     
  1. __asm__ __volatile__ (
  2. "mov %0, #55\n"
  3. "mov %1, #66\n"
  4. "xor %%eax, %%eax\n"
  5. )
 
  1. asm(
  2. "mov r0, r0\n\t"
  3. "mov r0, r0\n\t"
  4. "mov r0, r0\n\t"
  5. "mov r0, r0"
  6. );
 關(guān)于嵌入式匯編,可以參見如下文章
   <<ARM GCC Inline Assembler Cookbook>>
<<Using Inline Assembly With gcc>>
  
二.嵌入式匯編與C的數(shù)據(jù)交互

  一般嵌入式匯編是一段特定代碼,因此有可以從C語言變量中讀取數(shù)據(jù),或者把處理后的數(shù)據(jù)交給C程序.

  2.1 從C變量取值.
    一般是從局域變量中取值,按定義的先后,用%0到%9表示,最多10個變量.
   比如下代碼
      asm("add %1,%2"); 
    
  2.2 向C程序返回結(jié)果.
    這里要用更復(fù)雜的分段式表達(dá)式.完整的嵌入式匯編分為四大部分:
      匯編代碼部分(code),輸出部分(output operand list ),輸入部分(input operand list ),破壞段(clobber list)部分,每一部分用":"分開.
     
     其中匯編語句段就一般的匯編指令,可以是多句.

     其中輸出部分即是向C變量賦值的部分.
     我們看如下示例
    
      asm("mov %0, %1, ror #1" : "=r" (result) : "r" (value));
     這里的語句部分是 "mov %0,%1,ror 1",這里把%1的值賦給%0,并且與1作位與.

     :后是輸出部 "=r(result)", 
      而且"r" (value)是輸入部,
     這里破壞部省略.

  2.3 輸出部格式
     在上例中 =r(result), =表示只用輸出,r表示通用寄存器的值賦給變量,result表示輸出C變量名字.
    這個"=r(result)"的完整意思是把結(jié)果賦給result.
    其中除 =外,還有其它保留字
  •       = 只寫/輸出變量
  •       + 可讀可寫變量
  •       &  該輸出操作數(shù)不能使用輸入操作數(shù)相同的寄存器
     
    而輸出部的關(guān)健字除r外,還有其它很多.它們用來表示輸出變量與前一部分語句中操作寄存器的關(guān)系,
      
    r 把r0~r15的值賦給變量
    f 使用浮點(diǎn)的寄存器f0~f15
    m 任意內(nèi)存地址
    a, b.c d 表示要求使用寄存器eax/ax/al, ebx/bx/bl, ecx/cx/cl或edx/dx/dl
    
這里有一個完整的表格
   
ConstraintUsage in ARM stateUsage in Thumb state
fFloating point registers f0 .. f7Not available
hNot availableRegisters r8..r15
GImmediate floating point constantNot available
HSame a G, but negatedNot available
IImmediate value in data processing instructions
e.g. ORR R0, R0, #operand
Constant in the range 0 .. 255
e.g. SWI operand
JIndexing constants -4095 .. 4095
e.g. LDR R1, [PC, #operand]
Constant in the range -255 .. -1
e.g. SUB R0, R0, #operand
KSame as I, but invertedSame as I, but shifted
LSame as I, but negatedConstant in the range -7 .. 7
e.g. SUB R0, R1, #operand
lSame as rRegisters r0..r7
e.g. PUSH operand
MConstant in the range of 0 .. 32 or a power of 2
e.g. MOV R2, R1, ROR #operand
Constant that is a multiple of 4 in the range of 0 .. 1020
e.g. ADD R0, SP, #operand
mAny valid memory address
NNot availableConstant in the range of 0 .. 31
e.g. LSL R0, R1, #operand
ONot availableConstant that is a multiple of 4 in the range of -508 .. 508
e.g. ADD SP, #operand
rGeneral register r0 .. r15
e.g. SUB operand1, operand2, operand3
Not available
wVector floating point registers s0 .. s31Not available
XAny operand

     
 
 
       常見實(shí)例
      :"=&r" (__val), "=m" (*mem) 
      
 2.4 輸入部分格式
    可以看是輸入變量的聲明,格式:關(guān)系關(guān)健字(變量名) ,關(guān)系關(guān)健字與輸入段類型,,所以這一個段經(jīng)常可以省略.
   如 r(result)
   可以還可以加上%的限定,表示可以變量對應(yīng)的%0,%1之類變量可以交換位置,比如add加數(shù),放前放后均可.
  :"r"(result) 表示%0是C變量result的值
  : "%r"(x),"r"(y) 
  還有常量0表示與第一個輸出數(shù)相同
 如下示例
    asm("mov %0, %0, ror #1" : "=r" (value) : "0" (value))
  

 2.5 破壞段(clobber list)格式
   表示匯編代碼產(chǎn)生什么樣后果,一般是"memory",表示內(nèi)存發(fā)現(xiàn)變化
   :"memory"

   除此之多,還有cc,表示改變條件代碼寄存器(condition  code register),如果一個寄存器名字,如r12,表示代碼修改了r12.

  參見下面的代碼,其中省略了輸出段和輸入段
   
  1. asm volatile("mrs r12, cpsr\n\t"
  2. "orr r12, r12, #0xC0\n\t"
  3. "msr cpsr_c, r12\n\t" ::: "r12", "cc");
   
  1. asm volatile("mrs r12, cpsr\n"
  2. "bic r12, r12, #0xC0\n"
  3. "msr cpsr_c, r12" :: "X" (c) : "r12", "cc"
  1. __asm__ __volatile__ (
  2. "loop:\n"
  3. "ldrb r1, [%0], #1\n"
  4. "strb r1, [%1], #1\n"
  5. "cmp r1, #0\n"
  6. "bne loop\n"
  7. :
  8. : "r" (a), "r" (b)
  9. : "r0", "r1", "memory"
  10. );
2.6 使用把匯編代碼段定義成宏
  這時建議使用 __asm__來代替 __asm ,__volatile__代替 __valatile,這樣在ANSI C沒有編譯警告
  
  1. #define BYTESWAP(val) \
  2. __asm__ __volatile__ ( \
  3. "eor r3, %1, %1, ror #16\n\t" \
  4. "bic r3, r3, #0x00FF0000\n\t" \
  5. "mov %0, %1, ror #8\n\t" \
  6. "eor %0, %0, r3, lsr #8" \
  7. : "=r" (val) \
  8. : "0"(val) \
  9. : "r3", "cc" \
  10. );
  2.7 代碼段內(nèi)部標(biāo)簽,
    這個可以在一個代碼段使用標(biāo)簽,但是不能從一個段跳到另一個段的標(biāo)簽里.標(biāo)簽用1: 2:這樣的定義方法.用b 語句跳轉(zhuǎn) ,如 bne 1b
   參見如下實(shí)例
    
  1. #define __arch_compare_and_exchange_val_64_rel(mem, newval, oldval) \
  2. ({ \
  3. __typeof (*(mem)) __tmp; \
  4. __typeof (mem) __memp = (mem); \
  5. __asm __volatile (__ARCH_REL_INSTR "\n" \
  6. "1: ldarx %0,0,%1" MUTEX_HINT_REL "\n" \
  7. " cmpd %0,%2\n" \
  8. " bne 2f\n" \
  9. " stdcx. %3,0,%1\n" \
  10. " bne- 1b\n" \
  11. "2: " \
  12. : "=&r" (__tmp) \
  13. : "b" (__memp), "r" (oldval), "r" (newval) \
  14. : "cr0", "memory"); \
  15. __tmp; \
  16. })
   
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP