Assembly Language ट्यूटोरियल
विधानसभा भाषा के साथ शुरुआत करना
खोज…
टिप्पणियों
असेंबली एक सामान्य नाम है जो मशीन कोड के कई मानव-पठनीय रूपों के लिए उपयोग किया जाता है। यह स्वाभाविक रूप से विभिन्न सीपीयू (सेंट्रल प्रोसेसिंग यूनिट) के बीच बहुत भिन्न होता है, लेकिन एकल सीपीयू पर भी असेंबली की कई असंगत बोलियां मौजूद हो सकती हैं, प्रत्येक को अलग-अलग कोडांतरक द्वारा संकलित किया जाता है, सीपीयू निर्माता द्वारा परिभाषित समान मशीन कोड में।
यदि आप अपनी स्वयं की विधानसभा समस्या के बारे में प्रश्न पूछना चाहते हैं, तो हमेशा बताएं कि आप किस एचडब्ल्यू और किस असेंबलर का उपयोग कर रहे हैं, अन्यथा आपके प्रश्न का विस्तार से उत्तर देना मुश्किल होगा।
एकल विशेष सीपीयू की लर्निंग असेंबली विभिन्न सीपीयू पर मूल बातें सीखने में मदद करेगी, लेकिन हर एचडब्ल्यू आर्किटेक्चर में विवरणों में काफी अंतर हो सकता है, इसलिए नए प्लेटफॉर्म के लिए एएसएम सीखना इसे खरोंच से सीखने के करीब हो सकता है।
लिंक:
परिचय
असेंबली भाषा मशीन भाषा या मशीन कोड का एक मानव पठनीय रूप है जो बिट्स और बाइट्स का वास्तविक अनुक्रम है जिस पर प्रोसेसर तर्क संचालित होता है। बाइनरी, ऑक्टल या हेक्स की तुलना में सामान्य तौर पर मानविकी में पढ़ना और प्रोग्राम करना मानव के लिए आसान होता है, इसलिए मनुष्य आम तौर पर असेंबली भाषा में कोड लिखते हैं और फिर प्रोसेसर द्वारा समझी गई मशीन भाषा प्रारूप में परिवर्तित करने के लिए एक या अधिक प्रोग्राम का उपयोग करते हैं।
उदाहरण:
mov eax, 4
cmp eax, 5
je point
एक असेम्बलर एक प्रोग्राम है जो असेंबली लैंग्वेज प्रोग्राम को पढ़ता है, उसे पार्स करता है और संबंधित मशीन लैंग्वेज को प्रोड्यूस करता है। यह समझना महत्वपूर्ण है कि सी ++ जैसी भाषा के विपरीत, मानक दस्तावेज़ में परिभाषित एक एकल भाषा है, कई अलग-अलग विधानसभा भाषाएं हैं। प्रत्येक प्रोसेसर आर्किटेक्चर, ARM, MIPS, x86, आदि में एक अलग मशीन कोड है और इस प्रकार एक अलग विधानसभा भाषा है। इसके अतिरिक्त, कभी-कभी एक ही प्रोसेसर आर्किटेक्चर के लिए कई अलग-अलग विधानसभा भाषाएं होती हैं। विशेष रूप से, x86 प्रोसेसर परिवार के दो लोकप्रिय प्रारूप हैं जिन्हें अक्सर गैस सिंटैक्स के रूप में संदर्भित किया जाता है ( gas
GNU असेंबलर के लिए निष्पादन योग्य का नाम है) और इंटेल सिंटैक्स (x86 प्रोसेसर परिवार के प्रवर्तक के नाम पर)। वे अलग-अलग हैं, लेकिन इसके बराबर में आमतौर पर किसी भी प्रोग्राम को सिंटैक्स में लिखा जा सकता है।
आमतौर पर, प्रोसेसर का आविष्कारक प्रोसेसर और उसके मशीन कोड का दस्तावेज बनाता है और एक असेंबली भाषा बनाता है। यह केवल उस विशेष विधानसभा भाषा के लिए सामान्य है जिसका उपयोग केवल एक ही किया जाता है, लेकिन संकलक लेखकों के विपरीत भाषा मानक के अनुरूप होने का प्रयास करते हुए, प्रोसेसर के आविष्कारक द्वारा परिभाषित असेंबली भाषा आमतौर पर होती है, लेकिन हमेशा लोगों द्वारा उपयोग किए जाने वाले संस्करण जो कोडांतरक लिखते हैं ।
दो सामान्य प्रकार के प्रोसेसर हैं:
CISC (कॉम्प्लेक्स इंस्ट्रक्शन सेट कंप्यूटर): कई अलग-अलग और अक्सर जटिल मशीन भाषा निर्देश होते हैं
RISC (कम निर्देश सेट कंप्यूटर): इसके विपरीत, कम और सरल निर्देश हैं
असेंबली लैंग्वेज प्रोग्रामर के लिए, अंतर यह है कि CISC प्रोसेसर के पास सीखने के लिए बहुत सारे निर्देश हो सकते हैं लेकिन अक्सर किसी विशेष कार्य के लिए अनुकूल निर्देश होते हैं, जबकि RISC प्रोसेसर के पास कम और सरल निर्देश होते हैं, लेकिन किसी भी दिए गए ऑपरेशन के लिए असेंबली भाषा प्रोग्रामर की आवश्यकता हो सकती है एक ही काम करने के लिए और अधिक निर्देश लिखने के लिए।
अन्य प्रोग्रामिंग लैंग्वेज कंपाइलर कभी-कभी असेंबलर का उत्पादन करते हैं, जिसे बाद में असेंबलर कहकर मशीन कोड में संकलित किया जाता है। उदाहरण के लिए, संकलन के अंतिम चरण में अपने स्वयं के गैस असेंबलर का उपयोग करके जीसीसी । उत्पादित मशीन कोड को अक्सर ऑब्जेक्ट फ़ाइलों में संग्रहीत किया जाता है, जिसे लिंकर प्रोग्राम द्वारा निष्पादन योग्य में जोड़ा जा सकता है।
एक पूर्ण "टूलचैन" में अक्सर एक संकलक, कोडांतरक और लिंकर होते हैं। उसके बाद असेंबलीर और लिंकर को सीधे असेंबली भाषा में प्रोग्राम लिखने के लिए इस्तेमाल किया जा सकता है। जीएनयू दुनिया में बिन्यूटिल्स पैकेज में कोडांतरक और लिंकर और संबंधित उपकरण शामिल हैं; जो लोग पूरी तरह से असेंबली भाषा प्रोग्रामिंग में रुचि रखते हैं उन्हें gcc या अन्य संकलक पैकेज की आवश्यकता नहीं है।
छोटे माइक्रोकंट्रोलर को अक्सर असेंबली भाषा में या असेंबली लैंग्वेज के संयोजन में और सी या सी ++ जैसी एक या अधिक उच्च स्तरीय भाषाओं में प्रोग्राम किया जाता है। ऐसा इसलिए किया जाता है क्योंकि कोई व्यक्ति अक्सर ऐसे उपकरणों के लिए निर्देश सेट आर्किटेक्चर के विशेष पहलुओं का उपयोग अधिक कॉम्पैक्ट, कुशल कोड लिखने के लिए कर सकता है जो उच्च स्तर की भाषा में संभव होगा और ऐसे उपकरणों में अक्सर सीमित मेमोरी और रजिस्टर होते हैं। कई माइक्रोप्रोसेसरों का उपयोग एम्बेडेड सिस्टम में किया जाता है जो सामान्य प्रयोजन के कंप्यूटर के अलावा अन्य डिवाइस होते हैं जो अंदर माइक्रोप्रोसेसर होते हैं। ऐसे एम्बेडेड सिस्टम के उदाहरण टीवी, माइक्रोवेव ओवन और आधुनिक ऑटोमोबाइल के इंजन नियंत्रण इकाई हैं। ऐसे कई उपकरणों में कोई कीबोर्ड या स्क्रीन नहीं होती है, इसलिए एक प्रोग्रामर आम तौर पर एक सामान्य प्रयोजन के कंप्यूटर पर प्रोग्राम लिखता है, एक क्रॉस-एसेम्बलर चलाता है (तथाकथित क्योंकि इस तरह के असेंबलर एक अलग तरह के प्रोसेसर के लिए कोड का उत्पादन करता है, जिस पर वह चलता है ) और / या एक क्रॉस-कंपाइलर और क्रॉस लिंकर मशीन कोड का उत्पादन करने के लिए।
ऐसे उपकरणों के लिए कई विक्रेता हैं, जो प्रोसेसर के रूप में विविध हैं, जिसके लिए वे कोड का उत्पादन करते हैं। कई, लेकिन सभी प्रोसेसरों में GNU, sdcc, llvm या अन्य जैसे ओपन सोर्स सॉल्यूशन भी नहीं होते हैं।
मशीन कोड
विशेष रूप से देशी मशीन प्रारूप में डेटा के लिए मशीन कोड शब्द है, जिसे सीधे मशीन द्वारा संसाधित किया जाता है - आमतौर पर सीपीयू (सेंट्रल प्रोसेसिंग यूनिट) नामक प्रोसेसर द्वारा।
सामान्य कंप्यूटर आर्किटेक्चर ( वॉन न्यूमैन आर्किटेक्चर ) में सामान्य प्रयोजन प्रोसेसर (सीपीयू), सामान्य उद्देश्य मेमोरी - प्रोग्राम (ROM / RAM) और प्रोसेस्ड डेटा और इनपुट और आउटपुट डिवाइस (I / O डिवाइस) दोनों होते हैं।
इस वास्तुकला का मुख्य लाभ प्रत्येक घटक की सादगी और सार्वभौमिकता है - जब कंप्यूटर मशीनों की तुलना में (मशीन निर्माण में हार्ड-वायर्ड प्रोग्राम के साथ), या प्रतिस्पर्धी आर्किटेक्चर (उदाहरण के लिए हार्वर्ड आर्किटेक्चर कार्यक्रम की स्मृति को अलग करते हुए) डेटा)। नुकसान सामान्य प्रदर्शन थोड़ा खराब है। लंबे समय तक सार्वभौमिकता ने लचीले उपयोग के लिए अनुमति दी, जो आमतौर पर प्रदर्शन लागत से आगे निकल गई।
यह मशीन कोड से कैसे संबंधित है?
प्रोग्राम और डेटा को इन कंप्यूटरों में मेमोरी के रूप में संख्याओं में संग्रहित किया जाता है। डेटा से अलग कोड बताने का कोई वास्तविक तरीका नहीं है, इसलिए ऑपरेटिंग सिस्टम और मशीन ऑपरेटर सीपीयू संकेत देते हैं, जिस पर मेमोरी के सभी बिंदुओं को लोड करने के बाद मेमोरी का एंट्री पॉइंट प्रोग्राम शुरू होता है। सीपीयू तब प्रवेश बिंदु पर संग्रहीत अनुदेश (संख्या) को पढ़ता है, और इसे सख्ती से संसाधित करता है, क्रमिक रूप से अगले निर्देशों के रूप में अगले नंबर को पढ़ता है, जब तक कि कार्यक्रम खुद सीपीयू को निष्पादन के साथ जारी रखने के लिए कहीं और नहीं बताता है।
उदाहरण के लिए एक दो 8 बिट संख्या (एक साथ समूहीकृत किए गए 8 बिट्स 1 बाइट के बराबर हैं, यह 0-255 रेंज के भीतर एक अहस्ताक्षरित पूर्णांक संख्या है): 60
201
, जब Zilog Z80 CPU पर कोड के रूप में निष्पादित दो निर्देशों के रूप में संसाधित किया जाएगा: INC a
( a
बाद एक रजिस्टर में वृद्धि मूल्य) और RET
(उप-दिनचर्या से लौटते हुए, सीपीयू को स्मृति के विभिन्न भाग से निर्देशों को निष्पादित करने के लिए इंगित करता है)।
इस कार्यक्रम को परिभाषित करने के लिए एक मानव कुछ मेमोरी / फ़ाइल संपादक द्वारा उन नंबरों को दर्ज कर सकता है, उदाहरण के लिए हेक्स-एडिटर में दो बाइट्स: 3C C9
(दशमलव संख्या 60 और 201 बेस 16 एन्कोडिंग में लिखे गए)। यह मशीन कोड में प्रोग्रामिंग होगी।
मनुष्यों के लिए सीपीयू प्रोग्रामिंग के कार्य को आसान बनाने के लिए, एक असेम्बलर प्रोग्राम बनाए गए थे, जो टेक्स्ट फाइल को पढ़ने में सक्षम थे, जैसे कि:
subroutineIncrementA:
INC a
RET
dataValueDefinedInAssemblerSource:
DB 60 ; define byte with value 60 right after the ret
आउटपुट बाइट हेक्स-नंबर्स सीक्वेंस 3C C9 3C
, टारगेट प्लेटफॉर्म के लिए वैकल्पिक अतिरिक्त नंबरों के साथ लिपटे हुए: मार्किंग, ऐसे बाइनरी का कौन सा हिस्सा निष्पादन योग्य कोड है, जहां प्रोग्राम के लिए प्रवेश बिंदु (इसका पहला निर्देश) है, कौन से हिस्से एन्कोडेड हैं डेटा (निष्पादन योग्य नहीं), आदि।
ध्यान दें कि प्रोग्रामर ने अंतिम बाइट को "डेटा" के रूप में मान 60 के साथ निर्दिष्ट किया है, लेकिन सीपीयू के दृष्टिकोण से यह INC a
बाइट से किसी भी तरह से अलग नहीं है। यह निर्देशों के रूप में तैयार बाइट्स पर सीपीयू को सही ढंग से नेविगेट करने के लिए निष्पादन कार्यक्रम पर निर्भर है, और डेटा बाइट्स को केवल निर्देशों के लिए डेटा के रूप में संसाधित करता है।
इस तरह के आउटपुट को आमतौर पर ओएस ( ऑपरेटिंग सिस्टम - कंप्यूटर पर पहले से चल रहे एक मशीन कोड, कंप्यूटर के साथ हेरफेर करने में मदद करता है ) को मेमोरी में रखने से पहले इसे स्टोर किया जाता है, और इसके बाद सीपीयू को इंगित किया जाता है। कार्यक्रम का प्रवेश बिंदु।
CPU केवल मशीन कोड को प्रोसेस और निष्पादित कर सकता है - लेकिन कोई भी मेमोरी कंटेंट, यहां तक कि रैंडम वन, को इस तरह से प्रोसेस किया जा सकता है, हालांकि परिणाम यादृच्छिक हो सकता है, जिसका पता " क्रैश " से लगाया जा सकता है और OS द्वारा I / से डेटा की आकस्मिक क्षति को नियंत्रित किया जा सकता है। हे डिवाइस, या कंप्यूटर से जुड़े संवेदनशील उपकरणों की क्षति (घरेलू कंप्यूटर के लिए एक सामान्य मामला नहीं :))।
इसी तरह की प्रक्रिया कई अन्य उच्च स्तरीय प्रोग्रामिंग भाषाओं द्वारा की जाती है, जो स्रोत (प्रोग्राम के मानव पठनीय पाठ रूप) को संख्याओं में संकलित करते हैं, या तो मशीन कोड (सीपीयू के मूल निर्देश) का प्रतिनिधित्व करते हैं, या कुछ सामान्य में व्याख्या / संकर भाषाओं के मामले में। भाषा-विशिष्ट वर्चुअल मशीन कोड, जिसे दुभाषिया या वर्चुअल मशीन द्वारा निष्पादन के दौरान देशी मशीन कोड में और डिकोड किया जाता है।
कुछ संकलक संकलक के मध्यवर्ती चरण के रूप में असेंबलर का उपयोग करते हैं, स्रोत को पहले असेंबलर के रूप में अनुवाद करते हैं, फिर अंतिम मशीन कोड प्राप्त करने के लिए कोडांतरक उपकरण चला रहे हैं (GCC उदाहरण: gcc -S helloworld.c
चलाएं C प्रोग्राम का कोडांतरक संस्करण प्राप्त करने के लिए helloworld.c
)।
लिनक्स x86_64 के लिए हैलो दुनिया (इंटेल 64 बिट)
section .data
msg db "Hello world!",10 ; 10 is the ASCII code for a new line (LF)
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, 13
syscall
mov rax, 60
mov rdi, 0
syscall
यदि आप इस प्रोग्राम को निष्पादित करना चाहते हैं, तो आपको सबसे पहले नेटवाइड असेंबलर , nasm
, क्योंकि यह कोड इसके सिंटैक्स का उपयोग करता है। फिर निम्नलिखित कमांड्स का उपयोग करें (यह मानते हुए कि कोड फ़ाइल में है helloworld.asm
)। उन्हें क्रमशः संयोजन, लिंकिंग और निष्पादन के लिए आवश्यक है।
-
nasm -felf64 helloworld.asm
-
ld helloworld.o -o helloworld
-
./helloworld
कोड लिनक्स के sys_write
syscall का उपयोग करता है। यहाँ आप x86_64 वास्तुकला के लिए सभी syscalls की एक सूची देख सकते हैं। जब आप भी लिखने और बाहर निकलने के आदमी के पन्नों को खाते में लेते हैं, तो आप उपरोक्त कार्यक्रम को एक सी में अनुवाद कर सकते हैं जो ऐसा करता है और यह बहुत अधिक पठनीय है:
#include <unistd.h>
#define STDOUT 1
int main()
{
write(STDOUT, "Hello world!\n", 13);
_exit(0);
}
संकलन और लिंकिंग (पहले एक) और निष्पादन के लिए बस दो कमांड की आवश्यकता है:
-
gcc helloworld_c.c -o helloworld_c
। -
./helloworld_c
हैलो वर्ल्ड फॉर ओएस एक्स (x86_64, इंटेल सिंटैक्स गैस)
.intel_syntax noprefix
.data
.align 16
hello_msg:
.asciz "Hello, World!"
.text
.global _main
_main:
push rbp
mov rbp, rsp
lea rdi, [rip+hello_msg]
call _puts
xor rax, rax
leave
ret
इकट्ठा:
clang main.s -o hello
./hello
टिप्पणियाँ:
- सिस्टम कॉल के उपयोग को हतोत्साहित किया जाता है क्योंकि ओएस एक्स में सिस्टम कॉल एपीआई को स्थिर नहीं माना जाता है। इसके बजाय, सी लाइब्रेरी का उपयोग करें। ( एक ढेर अतिप्रवाह सवाल का संदर्भ )
- इंटेल अनुशंसा करता है कि एक शब्द से बड़ी संरचनाएं 16-बाइट सीमा पर शुरू होती हैं। ( इंटेल प्रलेखन के संदर्भ )
- ऑर्डर डेटा को रजिस्टरों के माध्यम से फ़ंक्शंस में पास किया जाता है: आरडीआई, आरसीआई, आरडीएक्स, आरएक्सएक्स, आर 8, और आर 9। ( सिस्टम वी एबीआई का संदर्भ )
विजुअल स्टूडियो 2015 में x86 असेंबली का निष्पादन
चरण 1 : फ़ाइल के माध्यम से एक खाली परियोजना बनाएं -> नई परियोजना ।
चरण 2 : प्रोजेक्ट समाधान पर राइट क्लिक करें और बिल्ड डिपेंडेंसी-> बिल्ड कस्टमाइज़ेशन चुनें ।
चरण 3 : चेकबॉक्स ".mm" की जाँच करें।
चरण 4 : "ओके" बटन दबाएं।
चरण 5 : अपनी विधानसभा फ़ाइल बनाएँ और इसमें लिखें:
.386
.model small
.code
public main
main proc
; Ends program normally
ret
main endp
end main
चरण 6 : संकलित करें!