當前位置:首頁 » 編程軟體 » 內聯匯編編譯

內聯匯編編譯

發布時間: 2022-11-12 03:37:16

1. 內聯匯編的GNU 匯編程序簡述

linux 中使用的基本匯編程序語法。GCC(用於 Linux 的 GNU C 編譯器)使用 AT&T 匯編語法。下面列出了這種語法的一些基本規則。 asm ( assembler template
: output operands (optional)
: input operands (optional)
: list of clobbered registers
(optional)
);
本例中,匯編程序模板由匯編指令組成。輸入操作數是充當指令輸入操作數使用的 C 表達式。輸出操作數是將對其執行匯編指令輸出的 C 表達式。
內聯匯編的重要性體現在它能夠靈活操作,而且可以使其輸出通過 C 變數顯示出來。因為它具有這種能力,所以 asm 可以用作匯編指令和包含它的 C 程序之間的介面。
一個非常基本但很重要的區別在於 簡單內聯匯編只包括指令,而 擴展內聯匯編包括操作數。要說明這一點,考慮以下示例: { int a=10, b; asm (movl %1, %%eax; movl %%eax, %0; :=r(b) /* output */ :r(a) /* input */ :%eax); /* clobbered register */}
在上例中,我們使用匯編指令使 b 的值等於 a。請注意以下幾點:
b 是輸出操作數,由 %0 引用,a 是輸入操作數,由 %1 引用。 r 是操作數的約束,它指定將變數 a 和 b 存儲在寄存器中。請注意,輸出操作數約束應該帶有一個約束修飾符 =,指定它是輸出操作數。 要在 asm 內使用寄存器 %eax,%eax 的前面應該再加一個 %,換句話說就是 %%eax,因為 asm 使用 %0、%1 等來標識變數。任何帶有一個 % 的數都看作是輸入/輸出操作數,而不認為是寄存器。 第三個冒號後的修飾寄存器 %eax 告訴將在 asm 中修改 GCC %eax 的值,這樣 GCC 就不使用該寄存器存儲任何其它的值。 movl %1, %%eax 將 a 的值移到 %eax 中, movl %%eax, %0 將 %eax 的內容移到 b 中。 因為 b 被指定成輸出操作數,因此當 asm 的執行完成後,它將反映出更新的值。換句話說,對 asm 內 b 所做的更改將在 asm 外反映出來。

2. 為什麼內聯匯編不把字元串名當作指針看待

不可能當指針看的,傳遞a的指針,當然用lea命令。

3. 請教C++中編譯64位程序的時候能否使用32位內聯匯編

從x64的設計來說,64-bit模式下是可以使用32-bit指令和大部分16-bit指令的(有一部分16-bit指令的編碼被重用了,所以不能用,還有一部分涉及段操作的也不能用),但是在long mode下運行的32-bit(兼容模式)代碼是不能使用64-bit指令和新寄存器的。
至於編譯器能否使用內嵌匯編,要看設計,cl64就徹底不允許任何嵌入匯編,但是icc、gcc是允許的。

4. gcc內聯匯編問題

簡單的說吧,"r"表示使用寄存器輸入value,即將value的值復制給某一寄存器;而「=r」表示使用寄存器輸出到value,即將某一寄存器的值賦給變數value。我沒有接觸過arm匯編,所以後面那個問題回答不了,抱歉。

5. codeblocks 如何編譯16位內聯匯編

class MyTest_Base
{
public:
MyTest_Base (int& status)
{
//do other job
// 由於資源不夠,對象構建失敗
// 把status置0,通知對象的構建者
status = 0;
}
};
void main()
{
int status;
MyTest_Base obj1(status);
// 檢查對象的構建是否成功
if(status ==0)
cout << "對象構建失敗" << endl;
}

程序運行的結果是:
對象構建失敗

在來看下面的程序:
class MyTest_Base
{
public:
MyTest_Base (int& status)
{
//do other job
// 由於資源不夠,對象構建失敗
// 把status置0,通知對象的構建者
status = 0;
}
virtual ~ MyTest_Base ()
{
cout << "銷毀一個MyTest_Base類型的對象" << endl;
}
};
void main()
{
int status;
MyTest_Base obj1(status);
// 檢查對象的構建是否成功
if(status ==0)
cout << "對象構建失敗" << endl;
}

6. VC6,內聯匯編怎麼樣獨立編譯並運行的方法

VC可以在CPP文件中嵌入匯編碼,但不能編譯.asm文件。
可以用masm編譯,然後同cpp編譯的obj文件連接在一起。而且可以把這個步驟自動化,選擇「工程」->"設置"->"Pre Link步驟",把編譯.asm成.obj 的命令加進去,就可以啦^ ^

7. 如何在C/C++使用內聯匯編

以下所說嵌入的匯編都是GUN 的C語言中嵌入ARM匯編。 1)2個參數的內嵌語句 這種形式的匯編用於簡單的語句,參數限制輸入和輸出語法格式如下: asm(code : output operand list : inputoperand list : clobber list); 匯編和C語句這間的聯系是通過上面asm聲明中可選的output operand list和input operand list。Clobber list後面再講。 下面是將C語言的一個整型變數傳遞給匯編,邏輯左移一位後在傳遞給C語言的另外一個整型變數。 /* Rotating bits example */ asm("mov %[result], %[value], ror#1" : [result] "=r" (y) : [value] "r" (x)); 每一個asm語句被冒號(:)分成了四個部分。          匯編指令放在第一部分中的「」中間。  "mov %[result], %[value], ror #1"          接下來是冒號後的可選擇的output operand list,每一個條目是由一對[](方括弧)和被他包括的符號名組成,它後面跟著限制性字元串,再後面是圓括弧和它括著的C變數。這個例子中只有一個條目。  [result] "=r" (y)          接著冒號後面是輸入操作符列表,它的語法和輸入操作列表一樣 [value] "r" (x) 為了增加代碼的可讀性,你可以使用換行,空格,還有C風格的注釋。 asm("mov %[result], %[value], ror#1"           : [result]"=r" (y) /* Rotation result. */           : [value]"r" (x) /* Rotated value. */           : /* No clobbers */ ); 在代碼部分%後面跟著的是後面兩個部分方括弧中的符號,它指的是相同符號操作列表中的一個條目。 %[result]表示第二部分的C變數y,%[value]表示三部分的C變數x; 符號操作符的名字使用了獨立的命名空間。這就意味著它使用的是其他的符號表。簡單一點就是說你不必關心使用的符號名在C代碼中已經使用了。在早期的C代碼中,循環移位的例子必須要這么寫: asm("mov %0, %1, ror #1" :"=r" (result) : "r" (value)) 在匯編代碼中操作數的引用使用的是%後面跟一個數字,%1代表第一個操作數,%2代碼第二個操作數,往後的類推。這個方法目前最新的編譯器還是支持的。但是它不便於維護代碼 實例代碼: 2) 帶.s文件的匯編 編譯命令: arm-linux-gcc  main.c Asmfile_gnu.s  -o mains main.c #include extern voidpcm8_2_pcm16(unsigned char* pIn, int nInlen, short* pOut); extern voidpcm16_2_pcm8(short* pIn, int nInlen,unsigned char* pOut); int main() {             unsigned char* pIn="1234";        short pInd[256];        unsigned char pOutd[256];        int nInlen=4;        int i = 0;        short pOut[256];        for(i=0;i<4;i++)                printf(" 0x%x  ",pIn[i]);        printf("\n");        memset((char *)pOut,0,256*2);        memset((char *)pInd,0,256*2);          memset((char *)pOutd,0,256*2);          pcm8_2_pcm16(pIn,nInlen,pOut);        for(i=0;i<4;i++)                printf(" 0x%x  ",pOut[i]);        printf("\n");        memcpy((char *)pInd,(char *)pOut,256*2);        pcm16_2_pcm8(pInd,nInlen,pOutd);        for(i=0;i<4;i++)                printf(" 0x%x  ",pOutd[i]);        printf("\n");          return 0; }   Asmfile_gnu.s .text .global pcm8_2_pcm16 .global pcm16_2_pcm8 #*******************************#  #********* ENCODER 實現將第一個輸入參數  #左移8位然後異或0x8000 然後拷貝到第三個參數  #DECODE 取第一個參數所指的數據先異或0x8000  #然後右移8位將數據拷貝到第三個參數  #******************************* pcm8_2_pcm16:        MOV R6,#0        MOV R7,#0 ENCODER:        LDRB R5,[R0,R6]        MOV  R8,R5,LSL#8        EOR  R9,R8,#0x8000       STRH R9,[R2,R7]        ADD  R7,R7,#2        ADD  R6,R6,#1       SUB  R1,R1,#1       CMP  R1,#0       BNE  ENCODER       B    OVER   pcm16_2_pcm8:        MOV  R6,#0        MOV  R7,#0 DECODE:        LDRH R5,[R0,R6]        EOR  R8,R5,#0x8000       MOV  R9,R8,LSR#8       STRB R9,[R2,R7]        ADD  R7,R7,#1        ADD  R6,R6,#2       SUB  R1,R1,#1       CMP  R1,#0       BNE  DECODE OVER:       .en

8. gcc 內聯匯編

如下,不懂VC下匯編的規則,不知道那個RADIX是怎麼和函數名聯系起來的,我就直接用數字3了。加了一些注釋方便你讀,另外,在具體運算的匯編前後,我加了連續的三個nop空指令方便你反匯編或者debug的時候看到底哪些是通過內聯匯編生成的指令,哪些是編譯器自己產生的。你可以自行去掉。

unsigned int Div_3(unsigned long long x, unsigned long long *pRemainder)
{
register void * x_addr asm ("ecx") = &x;

asm volatile("nop;nop;nop");
asm volatile ("movl (%%ecx), %%eax\n\t" /* low 32bit of x to eax */
"movl 4(%%ecx), %%edx\n\t" /* high 32bit to edx */
"movl $3, %%ebx\n\t" /* radix = 3 */
"div %%ebx\n\t"
"movl $0, 4(%1)\n\t" /* high 32bit of remainder is 0 */
"movl %%edx, (%1)\n\t" /* remainder */
: /* no output operands */
: "r" (x_addr), "r" (pRemainder)
: "eax", "ebx", "edx");
asm volatile("nop;nop;nop");
}

9. 剛接觸內聯匯編,下面哪裡出錯了。。。為什麼都可以運行。。。可以詳細的跟我講一下嗎

沒有出錯,確實都能運行,是gcc的編譯處理太智能了,理由如下:

①gcc的內聯匯編的約束是個很智能的有限約束,能從約束里知道你想怎麼寫:如代碼中的「:"=a"(rrr),:"a"(ccc)」就已經告訴了編譯器,要讓這段內聯匯編代碼的效果是「rrr=ccc;」,但是要根據上面的匯編代碼寫。

②因此,以上asm語句中的內聯匯編代碼,基本可以隨便寫。如:

⑴最簡單的什麼都不寫(調試前把匯編代碼全部注釋掉)如圖1

所以說,如果需要ebx干預結果,只能把約束拿掉。至於,都可以運行,那完全是gcc編譯器的功勞

10. 內聯匯編的介紹

內聯匯編,指在C語言中插入匯編語言,其是Linux中使用的基本匯編程序語法。

熱點內容
視頻伺服器新建ftp用戶 發布:2025-05-14 13:03:09 瀏覽:224
php花生 發布:2025-05-14 12:54:30 瀏覽:549
java人才 發布:2025-05-14 12:29:10 瀏覽:649
如何打開軟密碼 發布:2025-05-14 12:28:55 瀏覽:427
七牛存儲待遇 發布:2025-05-14 12:27:20 瀏覽:422
C語言a35a4a5 發布:2025-05-14 11:53:48 瀏覽:813
android隱藏item 發布:2025-05-14 11:43:56 瀏覽:328
javawebeclipse編譯 發布:2025-05-14 11:35:24 瀏覽:938
可編程式控制制器試題 發布:2025-05-14 11:25:32 瀏覽:122
dsp混合編程 發布:2025-05-14 11:23:10 瀏覽:251