AT AT & T是gas(GNU Assembler)的輸出語法,你不應該想太長時間。只需將它寫入C中,並使用-S開關生成彙編程序輸出。
例:
如果在源文件abc.c
main(){
int a = 7;
int b = 3;
int c = 2;
return (double)a/(double)b*(double)c;
}
鍵入以下程序,然後使用編譯gcc -S abc.c
我得到下面的彙編代碼:
.file "abc.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $7, -4(%rbp)
movl $3, -8(%rbp)
movl $2, -12(%rbp)
cvtsi2sd -4(%rbp), %xmm0
cvtsi2sd -8(%rbp), %xmm1
movapd %xmm0, %xmm2
divsd %xmm1, %xmm2
movapd %xmm2, %xmm1
cvtsi2sd -12(%rbp), %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.6.3-1) 4.6.3"
.section .note.GNU-stack,"",@progbits
它的功能應該足夠清楚:re在堆棧中爲3 int提供空間,在它們中存儲常數值,將它們轉換爲double(cvtsi2sd),執行除法(注意:你寫的順序爲div b, a
,結果在第二個寄存器中)。等等。顯而易見的是,編譯器現在不用費時地使用舊的FPU 8087指令集,有更簡單的方法來執行浮點運算而無需使用FPU堆棧。由於這個問題在目標系統上沒有提出任何問題,我將按照我的編譯器的說法來執行此類計算。由於對某些人來說可能還不清楚(我的回答是downvoted),所以我對gcc輸出進行了一些重新排序(以避免無用地移動)並添加了評論。唯一可能的缺陷是div的參數順序。在哪個寄存器中放置數據並得到結果取決於讀者。
.file "abc.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
# Load integer 7 (variable a), convert it to double
movl $7, -4(%rbp)
cvtsi2sd -4(%rbp), %xmm0
# Load integer 3, (variable b) convert it to double
movl $3, -8(%rbp)
cvtsi2sd -8(%rbp), %xmm1
# Load integer 2, (variable c) convert it to double
movl $2, -12(%rbp)
cvtsi2sd -12(%rbp), %xmm2
# a/b -> written "div b, a" result goes in a (%xmm0)
divsd %xmm1, %xmm0
# b * c -> result goes in c (%xmm2)
mulsd %xmm0, %xmm2
# convert result back to integer
cvttsd2si %xmm2, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.6.3-1) 4.6.3"
.section .note.GNU-stack,"",@progbits
在Linux上,你可以編譯運行並顯示結果(截斷爲int,並截斷爲256,因爲它是處理結果)簡單地做:
gcc abc.s ; ./a.out ; echo $?
爲了使答案更完整,您可以輕鬆地使用舊的FPU寫一個等效的程序(它沒有打擾設置FPU的截斷模式,所以你可能會得到5而不是4是其截斷到最接近的整數):
.file "abc.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
# Load integer 7 (variable a), convert it to double
movl $7, -4(%rbp)
# Load integer 3, (variable b) convert it to double
movl $3, -8(%rbp)
# Load integer 2, (variable c) convert it to double
movl $2, -12(%rbp)
fild -12(%rbp)
fild -8(%rbp)
fild -4(%rbp)
# a/b -> written "div b, a" result goes in a (%mm0)
fdivp %st(0), %st(1)
# b * c -> result goes in c (%mm2)
fmulp %st(0), %st(1)
# convert result back to integer
fist -4(%rbp)
movl -4(%rbp), %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.6.3-1) 4.6.3"
.section .note.GNU-stack,"",@progbits
「我也嘗試過使用fidi v和fimul ......「然後向我們展示你的嘗試。 – 2012-07-15 00:07:50