linux汇编字符长怎么看,linux – 在内联GNU汇编程序中获取字符串长...
使用GCC的內(nèi)聯(lián)asm來學(xué)習(xí)匯編的問題在于你花了一半的時間來學(xué)習(xí)gcc的內(nèi)聯(lián)匯編是如何工作的,而不是實(shí)際學(xué)習(xí)匯編.例如,這是我如何編寫相同的代碼:
#include
int getStringLength(const char *pStr){
int len;
__asm__ (
"repne scasb
"
"not %%ecx
"
"dec %%ecx"
:"=c" (len), "+D"(pStr) /*Outputs*/
:"c"(-1), "a"(0) /*Inputs*/
/* tell the compiler we read the memory pointed to by pStr,
with a dummy input so we don't need a "memory" clobber */
, "m" (*(const struct {char a; char x[];} *) pStr)
);
return len;
}
將此與您的示例進(jìn)行比較
>我沒有初始化len,因?yàn)閍sm將它聲明為輸出(= c).
>沒有必要復(fù)制pStr,因?yàn)樗且粋€局部變量.根據(jù)規(guī)范,我們已經(jīng)允許更改它(雖然因?yàn)樗莄onst我們不應(yīng)該修改它指向的數(shù)據(jù)).
>沒有理由告訴內(nèi)聯(lián)asm將Ptr放入eax,只是讓你的asm將它移動到edi.我只是把edi中的值放在第一位.請注意,由于edi中的值正在發(fā)生變化,我們不能僅將其聲明為“輸入”(按規(guī)范,內(nèi)聯(lián)asm不得更改輸入值).將其更改為讀/寫輸出可解決此問題.
>沒有必要讓asm零eax,因?yàn)槟憧梢杂邢拗茷槟阕?作為附帶好處,gcc將“知道”它在eax寄存器中有0,并且(在優(yōu)化版本中)它可以重用它(想想:檢查2個字符串的長度).
>我也可以使用約束來初始化ecx.如上所述,不允許更改輸入值.但是由于我將ecx定義為輸出,gcc已經(jīng)知道我正在改變它.
>由于ecx,eax和edi的內(nèi)容都是明確指定的,因此不再需要破壞任何內(nèi)容.
所有這些都使得(略微)更短和更有效的代碼.
但這太荒謬了.怎么了(我能說’哎呀’嗎?)你應(yīng)該知道這一切嗎?
如果目標(biāo)是學(xué)習(xí)asm,那么使用inline asm并不是你最好的方法(實(shí)際上我會說在大多數(shù)情況下,inline asm是bad idea).我建議您將getStringLength聲明為extern并將其完全寫入asm,然后將其與您的C代碼鏈接.
通過這種方式,您可以了解參數(shù)傳遞,返回值,保留寄存器(以及學(xué)習(xí)哪些寄存器必須保留以及哪些可以安全地用作劃痕),堆棧幀,如何將asm與C鏈接等等.所有對于內(nèi)聯(lián)asm而言,這比gobbledygook更有用.
總結(jié)
以上是生活随笔為你收集整理的linux汇编字符长怎么看,linux – 在内联GNU汇编程序中获取字符串长...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git 拉取远程其他分支代码_git切换
- 下一篇: java 面试什么是类_Java 面试题