該代碼存在一些問題 - 在我的系統中,它甚至沒有運行編譯器/彙編程序。主要的問題是,你需要$
前綴的所有文字,否則彙編器總是假設一個內存訪問:
asm("movl 8,%ecx"); // tries to access memory at address 8 => Segmentation fault
這必須
asm("movl $8,%ecx"); // Moves literal 8 into ecx
相應地調整所有其他指令。
另一個問題是下面的指令:
asm("cmpb 0,$esi"); // $esi is not a literal nor a register name
這必須
asm("cmpb $0,(%esi)"); // compare value at address stored in %esi with literal 0 (end of string)
我建議你編譯調試信息的代碼,例如
$ g++ -g -o sample sample.c
這是那麼很容易調試該程序:
$ gdb sample
(gdb) run
Starting program: sample
sh: cls: command not found
Vvedite stroky iz 0 i 1 (do 8 delementov) > 10101010
Program received signal SIGSEGV, Segmentation fault.
main (argc=1, argv=0x7fffffffe238) at sample.c:18
18 asm("movl 8,%ecx"); // current bit position
如您所見,調試器向您顯示導致分段錯誤的指令。
更新
的建議通過@Brett這爲我工作,使用單一asm
語句中的彙編代碼:
asm("leal s, %esi \n\t" // s => %esi
"movl $8, %ecx \n\t" // current bit position (+1)
"movl $0, %edx \n" // initialize result
"repeat: \n\t"
"movl $1, %eax \n\t" // Create bit mask in %eax
"dec %ecx \n\t" // Decrement rotation counter to shift mask bit to proper position
"rol %cl, %eax \n\t" // calculate value of current binary digit
"cmpb $0x31, (%esi) \n\t" // current digit == 1?
"jnz x \n\t" // no, skip
"add %eax, %edx \n" // add current value to %edx
"x: \n\t"
"inc %esi \n\t" // next address in input string
"cmpb $0, (%esi) \n\t" // end of string reached?
"jnz repeat \n\t" // no, continue
"movl %edx,a \n"); // store result in a variable
$ ./sample
Vvedite stroky iz 0 i 1 (do 8 delementov) > 10101010
4islo 170
我個人避免AT&T的語法,但不應該」你是用'$'加前綴所有立即數和所有帶有'%'的寄存器嗎? (例如,'cmpb 0,$ esi'這一行應該是'cmpb $ 0,%esi')。 – Michael
它看起來並不像我這樣的代碼真的非常接近完成這項工作。在你習慣於編寫彙編語言之前,通常最簡單的方法是用c,*來編寫一些工作代碼,然後編寫代碼(大致)在彙編語言中做同樣的事情。 –
每個'asm'語句都是獨立的。您不能假定寄存器保存您在每個「asm」塊之前或之後所假設的值。您可能想閱讀GCC內聯程序集中的[* good * tutorial](http://locklessinc.com/articles/gcc_asm/)。 –