2011-08-21 10 views
5

मैं लिनक्स में इनलाइन असेंबलर के बारे में कुछ चीजों को समझने की कोशिश कर रहा हूं।एएसएम इनलाइन संदेह

void test_func(Word32 *var){ 
    asm(" addl %0, %%eax" : : "m"(var)); 
    return; 
} 

यह कोडांतरक कोड निम्नलिखित उत्पन्न:: मैं निम्नलिखित समारोह का उपयोग कर रहा

.globl test_func 
.type test_func, @function 
test_func: 
     pushl %ebp 
     movl %esp, %ebp 
#APP 
# 336 "opers.c" 1 
     addl 8(%ebp), %eax 
# 0 "" 2 
#NO_APP 
     popl %ebp 
     ret 
     .size test_func, .-test_func 

यह योग वर मेम पते रजिस्टर बजाय मूल्य वर मूल्य EAX करने के लिए।

क्या रजिस्टर में var mem पता कॉपी किए बिना var value के बजाय var mem address का उपयोग करने के लिए एडीएल निर्देश बताने का कोई तरीका है?

सादर

+0

आपका इनलाइन एएसएम को परिभाषित नहीं करता क्या EAX में माना जाता है की कोशिश करो, तो जीसीसी वहाँ कुछ भी डाल सकता है ... क्या आप वास्तव में क्या करने के लिए कोशिश कर रहे हैं? – servn

उत्तर

3

यह वैक्स रजिस्टर मूल्य के बदले var mem पता के बदले var mem पता है।

हां, जीसीसी इनलाइन असेंबली का वाक्यविन्यास सुंदर आर्केन है। GCC Inline Assembly HOWTO"m" में प्रासंगिक अनुभाग से पैराफ्रेशिंग आपको मोटे तौर पर सी-चर के स्मृति स्थान देता है।

यह वही है जो आप उपयोग करते हैं जब आप केवल एक ऐसा पता चाहते हैं जिसे आप लिख या पढ़ सकते हैं। नोटिस मैंने कहा कि सी चर का स्थान कहा गया है, इसलिए %0Word32 *var के पते पर सेट है - आपके पास पॉइंटर के लिए पॉइंटर है। इनलाइन असेंबली ब्लॉक का सी अनुवाद EAX += *(&var) जैसा दिख सकता है क्योंकि आप कह सकते हैं कि "m" बाधा स्पष्ट रूप से सी चर का पता लेती है और आपको एक पता अभिव्यक्ति देती है, जिसे आप %eax में जोड़ते हैं।

क्या रजिस्टर में var mem पता कॉपी किए बिना var value के बजाय var mem address का उपयोग करने के लिए एडीएल निर्देश बताने का कोई तरीका है?

यह आपके मतलब पर निर्भर करता है। आप ढेर से var प्राप्त करने की आवश्यकता है, तो किसी को भिन्नता स्मृति गया है (@Bo Perssons उत्तर देखें), लेकिन आप (इनलाइन विधानसभा

बाधा "m"(*var) होने की जरूरत है में यह करने के लिए की जरूरत नहीं है के रूप में @fazo सुझाव)। इससे आपको मान की मेमोरी लोकेशन मिल जाएगी जो पर इंगित कर रहा है, इसकी ओर इशारा करते हुए स्मृति स्थान की बजाय।

उत्पन्न कोड है:

test_func: 
    pushl %ebp 
    movl %esp, %ebp 
    movl 8(%ebp), %eax 
#APP 
# 2 "test.c" 1 
    addl (%eax), %eax 
# 0 "" 2 
#NO_APP 
    popl %ebp 
    ret 

कौन सा एक छोटे से संदिग्ध है, लेकिन यह समझ में आता है के रूप में आप जीसीसी बताने के लिए है कि आप clobbered भूल गया (इनपुट/आउटपुट सूची में बिना संशोधित) %eax। फिक्सिंग कि asm("addl %0, %%eax" : : "m"(*var) : "%eax") उत्पन्न करता है:

movl 8(%ebp), %edx 
    addl (%edx), %eax 

कौन सा नहीं किसी भी बेहतर या अधिक इस मामले में सही है, लेकिन यह हमेशा याद करने के लिए एक अच्छा अभ्यास है। clobber list पर अनुभाग देखें और इनलाइन असेंबली के उन्नत उपयोग के लिए "memory" क्लॉबर पर विशेष ध्यान दें।

भले ही आप एक रजिस्टर में मेमोरी एड्रेस को स्पष्ट रूप से लोड नहीं करना चाहते (मैं स्पष्ट रूप से इसे कवर करूंगा। "r" को "m" से बाधा बदलने लगभग काम करने के लिए, प्रासंगिक अनुभागों में बदल जाती है लगती है (अगर हम पीटना सूची में %eax शामिल हैं):

movl 8(%ebp), %edx 
    addl %edx, %eax 

कौन सा लगभग सही है, तो हम सूचक मूल्य var में लोड है एक रजिस्टर, लेकिन अब हमें खुद को निर्दिष्ट करना है कि हम स्मृति से लोड हो रहे हैं। "m" साथ के रूप में ही

movl 8(%ebp), %edx 
addl (%edx), %eax 

: कोड बाधा मैच के लिए बदल रहा है (आमतौर पर अवांछनीय, मैं केवल यह पूर्णता के लिए दिखा रहा हूँ):

asm("addl (%0), %%eax" : : "r"(var) : "%eax"); 

देता है।

3

हाँ, क्योंकि आप उसे वर जो पता है दे। उसे * var दे दो।

चाहते:

void test_func(Word32 *var){ 
    asm(" addl %0, %%eax" : : "m"(*var)); 
    return; 
} 

मैं बिल्कुल याद नहीं है, लेकिन आप "आर" के साथ "मीटर" की जगह चाहिए?

मेमोरी ऑपरेंड का मतलब यह नहीं है कि यह उस पते से मूल्य लेगा। यह सिर्फ एक सूचक है

+0

ऐसा करना कि यह वैर वैल्यू प्राप्त करने के लिए विभिन्न पते के साथ% eax मान को ओवरराइट करेगा। – LooPer

1

नहीं, x86 प्रोसेसर के लिए कोई एड्रेसिंग मोड नहीं है जो दो स्तर पर अप्रत्यक्ष हो जाता है।

आपको सबसे पहले पॉइंटर को मेमोरी एड्रेस से लोड करना होगा और फिर पॉइंटर से परोक्ष रूप से लोड करना होगा।

0

void test_func(Word32 *var){ 
    asm(" mov %0, %%edx; \ 
    addl (%%edx), %%eax" : : "m"(var));  

    return; 
} 
संबंधित मुद्दे