2010-06-01 4 views

उत्तर

31

इनलाइन विधानसभा के लिए कोई समर्थन नहीं है, लेकिन आप सी के माध्यम से विधानसभा में लिखे कोड के साथ लिंक कर सकते हैं, सीजीओ साथ संकलन और import "C" का उपयोग कर, gmp.go में की तरह। आप वैकल्पिक रूप से असेंबली की शैली में लिख सकते हैं जो सीधे asm_linux_amd64.s की तरह गो के साथ संगत है, जिसके लिए फ़ंक्शन नाम "·" से शुरू होते हैं।

या, आप अब तक मेरे पसंदीदा तरीके से नासम और gccgo का उपयोग कर सकते हैं। (ध्यान दें कि नस्म "·" से शुरू होने वाले कार्यों का समर्थन नहीं करता है)।

hello.asm:

; Based on hello.asm from nasm 

    SECTION .data  ; data section 
msg: db "Hello World",10 ; the string to print, 10=cr 
len: equ $-msg  ; "$" means "here" 
       ; len is a value, not an address 

    SECTION .text  ; code section 

global go.main.hello  ; make label available to linker (Go) 
go.main.hello: 

    ; --- setup stack frame 
    push rbp   ; save old base pointer 
    mov rbp,rsp ; use stack pointer as new base pointer 

    ; --- print message 
    mov edx,len  ; arg3, length of string to print 
    mov ecx,msg  ; arg2, pointer to string 
    mov ebx,1  ; arg1, where to write, screen 
    mov eax,4  ; write sysout command to int 80 hex 
    int 0x80  ; interrupt 80 hex, call kernel 

    ; --- takedown stack frame 
    mov rsp,rbp ; use base pointer as new stack pointer 
    pop rbp  ; get the old base pointer 

    ; --- return 
    mov rax,0  ; error code 0, normal, no error 
    ret   ; return 

main.go:

package main 

func hello(); 

func main() { 
    hello() 
    hello() 
} 

और एक आसान Makefile:

main: main.go hello.o 
    gccgo hello.o main.go -o main 

hello.o: hello.asm 
    nasm -f elf64 -o hello.o hello.asm 

clean: 
    rm -rf _obj *.o *~ *.6 *.gch a.out main 

यहाँ एक काम "हैलो दुनिया" उदाहरण है

मैंपर कॉल करता हूं Main.go में 10 बार, केवल दो बार जांचें कि हैलो() ठीक से लौटता है।

ध्यान दें कि इंटरफ़ेस 80h को सीधे कॉल करना लिनक्स पर अच्छी शैली नहीं माना जाता है, और लिखित कार्यों को कॉल करना सी है "भविष्य का सबूत"। यह भी ध्यान रखें कि यह विशेष रूप से 64-बिट लिनक्स के लिए असेंबली है, और किसी भी तरह, आकार या रूप में प्लेटफॉर्म-स्वतंत्र नहीं है।

मुझे पता है कि यह आपके प्रश्न का सीधा जवाब नहीं है, लेकिन यह इनलाइनिंग की कमी में गो के साथ असेंबली का उपयोग करने के लिए सबसे आसान मार्ग है। यदि आपको वास्तव में इनलाइनिंग की आवश्यकता है, तो ऐसी स्क्रिप्ट लिखना संभव है जो स्रोत फ़ाइलों से इनलाइन असेंबली निकालता है और इसे उपरोक्त पैटर्न का पालन करने के तरीके में तैयार करता है। पर्याप्त नजदीक? :)

जाओ, सी और एनएएसएम के लिए

त्वरित उदाहरण: gonasm.tgz

अद्यतन: gccgo की बाद के संस्करणों जी ध्वज की जरूरत है और केवल "main.hello" "के बजाय जरूरत है go.main.hello "। गो, सी और यास्म के लिए एक अद्यतन उदाहरण यहां दिया गया है: goyasm.tgz

23

इन-लाइन असेंबलर भाषा कोड का समर्थन करने के लिए गो प्रोग्रामिंग भाषा में कोई सुविधा नहीं है, और ऐसा करने की कोई योजना नहीं है। जाओ assembler और C में लिखे गए दिनचर्या से जोड़ने का समर्थन करता है। एक प्रयोगात्मक सुविधा है जो SWIG support को जाने के लिए जोड़ती है।

+0

+1 एक संदर्भ के लिए एक लिंक इस जवाब सही होगा;) – OscarRyz

+0

@OscarReyes: हो गया – peterSO

+0

+1 अब यह एकदम सही है! :) – OscarRyz

3

मानक गो कंपाइलर (यानी: 8 जी + 8 एल, जीसीजीओ) में अनुकूलन पास मूल रूप से बाइनरी रूप में कच्चे निर्देशों के साथ काम कर रहा है। इस प्राथमिक कारण है कि जाओ संकलक इनलाइन विधानसभा अनुमति नहीं देता है - वर्तमान में कोई रास्ता नहीं है (यह लागू नहीं है) संकलक उपयोगकर्ता के आपूर्ति की इनलाइन विधानसभा कोड से संकलक उत्पन्न विधानसभा भेद करने के लिए नहीं है। दूसरे शब्दों में, कंपाइलर आर्किटेक्चर की वजह से कंपाइलर इनलाइन असेंबली के लिए कोई समर्थन नहीं है।

वहाँ (जाता है कि: अन्य जाओ compilers) जाओ भाषा में ही जो अन्य जाओ भाषा कार्यान्वयन रोकने की जाएगी में पाठ्यक्रम कुछ भी नहीं की है इनलाइन विधानसभा के लिए समर्थन करने के लिए। इनलाइन असेंबली एक कंपाइलर-विशिष्ट निर्णय है - इसे गो भाषा के साथ ही बहुत कम करना है।

किसी भी मामले में, इनलाइन असेंबली असुरक्षित है क्योंकि इसे गो के प्रकार सिस्टम द्वारा शुद्धता के लिए चेक नहीं किया जा सकता है। ऐसा लगता है कि किसी भी फ़ंक्शन को कार्यान्वित करना बेहतर है जिसके लिए सी जैसी भाषा में इनलाइन असेंबली का उपयोग करना आवश्यक है, और सी से फ़ंक्शन को कॉल करें।

+1

बेहतर है कि इनलाइन एएसएम का उपयोग न करें, सी और यूनिक्स के मूल संस्करण को इसकी आवश्यकता नहीं है या इसे कार्यान्वित नहीं किया गया है, यह कोड को अयोग्य बनाता है और – uriel

10

नहीं, आप नहीं कर सकते, लेकिन जाने वाले कंपाइलर का उपयोग कर केवल एक समारोह के असेंबली कार्यान्वयन को आसान बनाना आसान है। असेंबली का उपयोग करने के लिए "आयात सी" का उपयोग करने की कोई आवश्यकता नहीं है।

http://golang.org/src/pkg/math/abs.go:

गणित पुस्तकालय से एक उदाहरण पर एक नजर डालें पेट समारोह इस फाइल जाना में घोषित किया जाता है। http://golang.org/src/pkg/math/abs_amd64.s में, (इस फ़ाइल में बार में पेट के एक कार्यान्वयन भी है, लेकिन यह निर्यात नहीं कर रहा है के रूप में यह एक लोअर केस नाम है।)

package math 

// Abs returns the absolute value of x. 
// 
// Special cases are: 
// Abs(±Inf) = +Inf 
// Abs(NaN) = NaN 
func Abs(x float64) float64 

फिर, पेट में इंटेल 64 बिट के लिए लागू किया गया है इस फाइल:

// func Abs(x float64) float64 
TEXT ·Abs(SB),NOSPLIT,$0 
    MOVQ $(1<<63), BX 
    MOVQ BX, X0 // movsd $(-0.0), x0 
    MOVSD x+0(FP), X1 
    ANDNPD X1, X0 
    MOVSD X0, ret+8(FP) 
    RET 
संबंधित मुद्दे