نحوه راه اندازی گوشی های هوشمند و رایانه های شخصی پرتال اطلاعاتی
  • خانه
  • ویندوز 10
  • نکاتی در مورد برنامه نویسی به زبان اسمبلی شیرجه زدن در اسمبلر

نکاتی در مورد برنامه نویسی به زبان اسمبلی شیرجه زدن در اسمبلر

امروزه تعداد زیادی زبان برنامه نویسی سطح بالا وجود دارد. در مقابل پس زمینه آنها، برنامه نویسی به یک زبان سطح پایین - زبان اسمبلی - ممکن است در نگاه اول چیزی منسوخ و غیرمنطقی به نظر برسد. با این حال، فقط به نظر می رسد. باید پذیرفت که اسمبلر در واقع زبان پردازنده است، به این معنی که تا زمانی که پردازنده ها وجود دارند نمی توان از آن صرف نظر کرد. از مزایای اصلی برنامه نویسی به زبان اسمبلی می توان به حداکثر سرعت و حداقل اندازه برنامه های به دست آمده اشاره کرد.

معایب اغلب تنها به دلیل تمایل بازار مدرن به ترجیح کمیت بر کیفیت است. رایانه های مدرن به راحتی می توانند با درهم ریختگی دستورات عملکردهای سطح بالا کنار بیایند، و اگر آسان نیست - لطفا سخت افزار دستگاه خود را ارتقا دهید! این قانون برنامه نویسی تجاری است. اگر ما در مورد برنامه نویسی برای روح صحبت می کنیم، یک برنامه فشرده و زیرک که در اسمبلر نوشته شده است، تأثیر بسیار دلپذیرتری نسبت به یک برنامه ریزی سطح بالا که با یکسری عملیات غیرضروری سنگین است، به جا می گذارد. این عقیده وجود دارد که فقط تعداد معدودی می توانند به زبان اسمبلی برنامه ریزی کنند. این درست نیست. البته برنامه نویسان اسمبلر با استعداد را می توان یک دست حساب کرد، اما تقریباً در هر زمینه ای از فعالیت های انسانی این گونه است. تعداد زیادی راننده آس وجود ندارد، اما همه می توانند نحوه رانندگی ماشین را یاد بگیرند - میل وجود دارد. پس از خواندن این سری مقالات، به یک هکر سرسخت تبدیل نخواهید شد. با این حال، یک نمای کلی دریافت خواهید کرد و راه های ساده برنامه نویسی به زبان اسمبلی برای ویندوز را با استفاده از توابع داخلی و دستورالعمل های ماکرو کامپایلر آن خواهید آموخت. طبیعتاً برای تسلط بر برنامه نویسی ویندوز باید مهارت و تجربه ویندوز را داشته باشید. در ابتدا چیز زیادی متوجه نخواهید شد، اما به این دلیل ناامید نشوید و ادامه دهید: با گذشت زمان، همه چیز سر جای خود قرار می گیرد.

بنابراین، برای شروع برنامه نویسی، حداقل به یک کامپایلر نیاز داریم. کامپایلر برنامه ای است که کد منبع نوشته شده توسط یک برنامه نویس را به کد ماشین قابل اجرا توسط یک پردازنده ترجمه می کند. عمده آموزش های زبان اسمبلی بر روی استفاده از بسته MASM32 (مجموعه کننده ماکرو سافت) متمرکز است. اما من در قالب تنوع و به چند دلیل دیگر، شما را با کامپایلر جوان FASM (Flat Assembler) که به سرعت در حال محبوبیت است آشنا می کنم. نصب و استفاده از این کامپایلر بسیار آسان است، جمع و جور و سریع است، دارای یک نحو ماکرو غنی و بزرگ است که به شما امکان می دهد بسیاری از کارهای روتین را خودکار کنید. با انتخاب فلت اسمبلر برای ویندوز می توانید آخرین نسخه آن را از وب سایت دانلود کنید. برای نصب FASM، یک پوشه، به عنوان مثال "D: \ FASM" ایجاد کنید و محتویات بایگانی فشرده دانلود شده را در آن باز کنید. FASMW.EXE را اجرا کنید و بدون تغییر چیزی ببندید. به هر حال، اگر از یک اکسپلورر استاندارد استفاده می‌کنید و پسوند فایل نمایش داده نمی‌شود (مثلاً EXE)، توصیه می‌کنم Tools -> Folder Options -> View را اجرا کنید و تیک گزینه Hide extensions for registered files type را بردارید. پس از اولین راه اندازی کامپایلر، یک فایل پیکربندی باید در پوشه ما - FASMW.INI ظاهر شود. آن را با یک دفترچه یادداشت استاندارد باز کنید و 3 خط در پایین آن اضافه کنید:

Fasminc = D: \ FASM \ شامل
شامل = D: \ FASM \ شامل

اگر FASM را به مکان دیگری باز کردید، مسیر خود را جایگزین «D: \ FASM» کنید. FASMW.INI را ذخیره کرده و ببندید. با نگاهی به آینده، به طور خلاصه توضیح خواهم داد که چگونه از کامپایلر استفاده خواهیم کرد:
1. متن برنامه را می نویسیم یا متن نوشته شده قبلی ذخیره شده در فایل asm را باز می کنیم یا متن برنامه را از کلیپ بورد با ترکیبی Paste می کنیم.
2. برای کامپایل و اجرای برنامه F9 یا فقط برای کامپایل Ctrl + F9 را فشار دهید. اگر متن برنامه هنوز ذخیره نشده باشد، کامپایلر از شما می خواهد که آن را قبل از کامپایل ذخیره کنید.
3. اگر برنامه شروع شده است، آن را برای عملکرد صحیح آزمایش می کنیم، در غیر این صورت، به دنبال خطاهایی می گردیم که خام ترین آنها را کامپایلر به ما نشان می دهد یا به طور ظریفی به آنها اشاره می کند.
خوب، اکنون می توانیم تمرین مورد انتظار را شروع کنیم. ما FASMW.EXE خود را راه اندازی می کنیم و کد اولین برنامه خود را در آن تایپ می کنیم:

شامل "% fasminc% / win32ax.inc"

داده ها
عنوان db "اولین برنامه من."، 0
متن db "سلام به همه!"، 0

کد
شروع:

فراخوانی ExitProcess، 0

روی Run -> Run یا F9 روی صفحه کلید خود کلیک کنید. در پنجره ذخیره، نام فایل و پوشه ذخیره را مشخص کنید. توصیه می شود به ذخیره هر برنامه در یک پوشه جداگانه عادت کنید تا در آینده گیج نشوید، زیرا ممکن است هر برنامه دارای دسته ای از فایل ها باشد: تصاویر، نمادها، موسیقی و غیره. اگر کامپایلر خطایی ایجاد کرد، خط مشخص شده را به دقت بررسی کنید - شاید یک کاما یا فاصله را از دست داده باشید. همچنین باید توجه داشته باشید که کامپایلر به حروف کوچک و بزرگ حساس است، بنابراین داده ها و داده ها به عنوان دو دستورالعمل متفاوت در نظر گرفته می شوند. اگر همه کارها را به درستی انجام داده باشید، نتیجه ساده ترین جعبه پیام خواهد بود (شکل 1). حالا بیایید بفهمیم که در متن برنامه چه نوشته ایم. در خط اول با دستور include یک متن بزرگ از چندین فایل را در برنامه خود قرار دادیم. یادتونه موقع نصب 3 خط توی فایل ini FASM نوشتیم؟ حالا% fasminc% در متن برنامه به معنای D: \ FASM \ INCLUDE یا مسیری است که شما مشخص کرده‌اید. دستورالعمل include، همانطور که بود، متنی را از فایل دیگری در مکان مشخص شده درج می کند. فایل WIN32AX.INC را در پوشه include با استفاده از notepad یا در خود fasma باز کنید و مطمئن شوید که متنی از win32a.inc، macro / if.inc را به طور خودکار به برنامه خود اضافه کرده ایم (ضمیمه) ) دستورالعمل های ماکرو و مجموعه ای رایج از کتابخانه های عملکرد ویندوز. به نوبه خود، هر یک از فایل های ارائه شده می تواند حاوی چندین فایل دیگر باشد و این زنجیره می تواند فراتر از افق باشد. با کمک فایل های شامل، نوعی زبان سطح بالا را سازماندهی می کنیم: برای جلوگیری از روال توصیف هر تابع به صورت دستی، کل کتابخانه ها را برای توصیف عملکردهای استاندارد ویندوز به هم وصل می کنیم. آیا واقعاً همه اینها برای چنین برنامه کوچکی ضروری است؟ نه، این چیزی شبیه به "ست آقایان برای همه موقعیت ها" است. هکرهای واقعی، البته، همه چیز را به هم وصل نمی کنند، اما ما فقط در حال یادگیری هستیم، بنابراین برای اولین بار قابل بخشش است.

در مرحله بعد، بخش داده - .data را تعیین کرده ایم. در این بخش، دو متغیر Caption و Text را اعلام می کنیم. اینها دستورات خاصی نیستند، بنابراین نام آنها را می توان به دلخواه تغییر داد، حتی اگر a و b، اگر فقط بدون فاصله باشد و به زبان روسی نباشد. خوب، شما نمی توانید متغیرها را با کلمات رزرو شده، به عنوان مثال، کد یا داده فراخوانی کنید، اما می توانید code_ یا data1 را فراخوانی کنید. دستور db به معنای "تعریف بایت" است. البته، تمام این متن در یک بایت قرار نمی گیرد، زیرا هر کاراکتر جداگانه یک بایت کامل را اشغال می کند. اما در این حالت فقط با این دستور یک متغیر اشاره گر تعریف می کنیم. این شامل آدرسی است که اولین کاراکتر رشته در آن ذخیره می شود. متن رشته در نقل‌قول‌ها نشان داده می‌شود و در صورت تمایل، نقل‌قول‌ها را می‌توان هم «چنین» و هم «چنین» تنظیم کرد - اگر فقط نقل‌قول اولیه با نقل قول پایانی یکسان باشد. صفر بعد از کاما یک بایت تهی به انتهای رشته اضافه می کند که نشان دهنده پایان رشته است (تهی پایان دهنده). سعی کنید این صفر را همراه با کاما در خط اول حذف کنید و ببینید چه چیزی به دست می آورید. در خط دوم در این مثال خاص، می توانید بدون صفر انجام دهید (ما آن را همراه با کاما حذف می کنیم - در غیر این صورت کامپایلر یک خطا را نشان می دهد)، اما این کار فقط به این دلیل کار می کند که در مثال ما، بخش بعدی بلافاصله پس از دوم شروع می شود. خط، و کامپایلر به طور خودکار یک دسته از صفرها را وارد می کند که قسمت قبلی را تراز می کند. به طور کلی صفر در انتهای خطوط متن الزامی است! بخش بعدی بخش کد برنامه اجرایی - .code است. در ابتدای بخش یک شروع وجود دارد: برچسب. یعنی از همین جاست که برنامه ما شروع به اجرا می کند. اولین دستور دستور ماکرو invoke است. این API MessageBox داخلی ویندوز را فراخوانی می کند. توابع API (رابط برنامه نویسی برنامه) کار در سیستم عامل را بسیار ساده می کند. ما به نوعی از سیستم عامل می خواهیم که برخی از اقدامات استاندارد را انجام دهد، و آن را انجام می دهد و پس از اتمام، نتیجه کار انجام شده را به ما برمی گرداند. پس از نام تابع، پارامترهای آن با کاما از هم جدا شده است. تابع MessageBox دارای پارامترهای زیر است:

پارامتر اول باید شامل دسته پنجره مالک باشد. دسته چیزی شبیه شماره شخصی است که توسط سیستم عامل برای هر شی (فرآیند، پنجره و غیره) صادر می شود. 0 در مثال ما به این معنی است که پنجره مالک ندارد، به خودی خود است و به هیچ پنجره دیگری وابسته نیست.
پارامتر دوم یک اشاره گر به آدرس حرف اول متن پیام است که با پایان دهنده تهی فوق الذکر خاتمه می یابد. برای درک واضح اینکه این فقط یک آدرس است، اجازه دهید این آدرس را 2 بایت درست در فراخوانی تابع تغییر دهیم: MessageBox، 0، Text + 2، Caption، MB_OK را فراخوانی کنید و مطمئن شوید که اکنون متن بدون دو حرف اول نمایش داده می شود. .
سوم - نشانگر آدرس حرف اول سرصفحه پیام.
4 - سبک پیام. شما می توانید لیستی از این سبک ها را پیدا کنید، به عنوان مثال، در INCLUDE \ EQUATES \ USER32.INC. برای انجام این کار، بهتر است از جستجوی Notepad برای یافتن سریع MB_OK و بقیه موارد استفاده کنید. در آنجا، متأسفانه، هیچ توضیحی وجود ندارد، اما از نام سبک معمولاً می توانید هدف آن را حدس بزنید. به هر حال، همه این سبک ها را می توان با یک عدد به معنای یک سبک یا ترکیبی از آنها جایگزین کرد، به عنوان مثال: MB_OK + MB_ICONEXCLAMATION. USER32.INC حاوی مقادیر هگزادسیمال است. می توانید آنها را در این فرم استفاده کنید یا در حالت مهندسی ماشین حساب استاندارد ویندوز آنها را به اعشار تبدیل کنید. اگر با سیستم های اعداد آشنا نیستید و نمی دانید اعشاری چقدر با هگزادسیمال متفاوت است، پس 2 راه دارید: یا با این موضوع در اینترنت آشنا شوید / در یک کتاب درسی / از یک دوست بپرسید، یا این کار را تا زمان بهتر ترک کنید. بارها و سعی کنید بدون این اطلاعات انجام دهید. در اینجا من حتی اطلاعات مختصری در مورد سیستم های اعداد ارائه نمی کنم با توجه به این واقعیت که حتی بدون من تعداد زیادی مقاله و صفحات در هر سطح قابل تصوری در مورد آنها نوشته شده است.

به قوچ های خودمان برگردیم. برخی از سبک ها را نمی توان همزمان استفاده کرد - برای مثال، MB_OKCANCEL و MB_YESNO. دلیل آن این است که مجموع مقادیر عددی آنها (1 + 4 = 5) با مقدار سبک دیگری - MB_RETRYCANCEL مطابقت دارد. حالا با پارامترهای تابع آزمایش کنید تا مطالب کاربردی تر شود و به جلو می رویم. تابع MessageBox اجرای برنامه را متوقف می کند و منتظر اقدام کاربر می ماند. پس از اتمام، تابع نتیجه عملکرد کاربر را به برنامه برمی گرداند و برنامه به کار خود ادامه می دهد. فراخوانی تابع ExitProcess روند برنامه ما را پایان می دهد. این تابع تنها یک پارامتر دارد، کد خروج. معمولاً اگر برنامه به طور عادی خارج شود، این کد صفر است. برای درک بهتر آخرین خط کد ما - .end start - کد معادل را با دقت مطالعه کنید: فرمت PE GUI 4.0

شامل "% fasminc% / win32a.inc"

بخش ".data" داده قابل خواندن قابل نوشتن

عنوان db "اولین برنامه ما."، 0
متن db "اسمبلر FASM آسان است!"، 0

بخش ".code" کد قابل خواندن قابل اجرا
شروع:
Invoke MessageBox، 0، Text، Caption، MB_OK
فراخوانی ExitProcess، 0

بخش ".idata" داده های وارداتی قابل خواندن قابل نوشتن است
کتابخانه KERNEL32، "KERNEL32.DLL"، \
USER32، "USER32.DLL"

وارد کردن KERNEL32، \
ExitProcess، "ExitProcess"

وارد کردن USER32، \
MessageBox، "MessageBoxA"

برای کامپایلر، تقریباً مشابه مثال قبلی است، اما برای ما این متن شبیه یک برنامه متفاوت است. من به طور خاص این مثال دوم را ذکر کردم تا در همان ابتدا ایده ای در مورد استفاده از دستورالعمل های ماکرو بدست آورید و از این پس، با انتقال از یک فایل متصل به فایل دیگر، به طور مستقل به کد واقعی برنامه پنهان شده در زیر پرده ماکروها برسید. بیایید سعی کنیم تفاوت ها را دریابیم. اولین چیزی که خیلی قابل توجه نیست، اما ارزش توجه ویژه را دارد، این است که ما به متن برنامه متصل می شویم نه win32ax، بلکه فقط win32a. ما یک مجموعه بزرگ را رها کرده ایم و خود را به یک مجموعه کوچک محدود کرده ایم. ما سعی خواهیم کرد بدون اتصال همه چیز پشت سر هم از win32ax انجام دهیم، اگرچه فعلاً هنوز به مقداری از آن نیاز داریم. بنابراین، با توجه به ماکروهای win32ax، برخی از تعاریف را به صورت دستی می نویسیم. به عنوان مثال، یک ماکرو از فایل win32ax:
داده‌های ماکرو (بخش «داده‌ها» قابل خواندن قابل نوشتن)

در زمان کامپایل، به طور خودکار داده ها را با بخش ".data" قابل خواندن قابل نوشتن جایگزین می کند. از آنجایی که ما این ماکرو را در متن برنامه قرار نداده ایم، باید تعریف دقیقی از بخش را خودمان بنویسیم. بر اساس قیاس، می توانید دلایل بقیه تغییرات در متن برنامه را در مثال دوم بیابید. ماکروها به شما کمک می کنند از دردسر نوشتن برنامه های بزرگ جلوگیری کنید. بنابراین، شما فقط باید فوراً به آنها عادت کنید و فقط بعداً آنها را دوست خواهید داشت =). سعی کنید خودتان با استفاده از متن ماکروهای استفاده شده در win32ax تفاوت بین مثال اول و دوم را بفهمید. من فقط می گویم که در نقل قول ها می توانید هر نام دیگری را برای بخش داده یا کد مشخص کنید - به عنوان مثال: بخش "ویروس" کد قابل خواندن قابل اجرا. این فقط یک نام بخش است و یک فرمان یا عملگر نیست. اگر همه چیز را فهمیدید، از قبل می توانید ویروس خود را بنویسید. به من اعتماد کنید، این بسیار آسان است. فقط عنوان و متن پست را تغییر دهید:
عنوان db "ویروس خطرناک."، 0

متن db "سلام، من یک ویروس تروجان بسیار خطرناک هستم و در حال انتشار از طریق اینترنت هستم."، 13، \
"از آنجایی که نویسنده من نمی تواند ویروس های مضر بنویسد، شما باید به من کمک کنید."، 13، \
"لطفا موارد زیر را انجام دهید:"، 13، \
"1.Erase the Directory C: \ Windows and C: \ Program files on your disk", 13, \
"2. این فایل را برای همه کسانی که می شناسید ارسال کنید"، 13، \
"پیشاپیش متشکرم."، 0

عدد 13 کد کاراکتر بازگشتی کالسکه برای سیستم های مایکروسافت است. کاراکتر \ در نحو FASM برای ترکیب چندین خط در یک خط استفاده می‌شود، بدون آن، یک خط بسیار طولانی از لبه صفحه خارج می‌شود. به عنوان مثال، می توانیم start: را بنویسیم، یا st \ را بنویسیم
ar \
t:

کامپایلر تفاوت بین گزینه اول و دوم را متوجه نخواهد شد.
خوب، برای افزایش شجاعت در "ویروس" ما، می توانید MB_OK را با MB_ICONHAND یا به سادگی عدد 16 را جایگزین کنید. در این صورت، پنجره به سبک یک پیام خطا خواهد بود و تأثیر چشمگیرتری بر روی قربانی "" ایجاد می کند. عفونت" (شکل 2).

برای امروز کافی است. برای شما آرزوی موفقیت دارم و به زودی شما را می بینم!
همه نمونه های ارائه شده برای درست کارکردن بر روی ویندوز XP تست شده اند و به احتمال زیاد روی سایر نسخه های ویندوز کار خواهند کرد، اما من هیچ تضمینی برای درست کارکردن آنها بر روی کامپیوتر شما نمی دهم. شما می توانید کدهای منبع برنامه ها را در انجمن پیدا کنید.

برنامه نویسی به زبان اسمبلی

این بخش از دوره آموزشی اصول برنامه نویسی زبان اسمبلی برای معماری Win32 را پوشش می دهد.

تمام فرآیندهای یک ماشین در پایین ترین سطح سخت افزاری فقط توسط دستورات زبان ماشین (دستورالعمل ها) هدایت می شوند. زبان اسمبلی نمایش نمادین زبان ماشین است... اسمبلر به شما امکان می دهد برنامه های کوتاه و سریع بنویسید. با این حال، این فرآیند بسیار وقت گیر است. برای نوشتن موثرترین برنامه، به دانش کافی از ویژگی های دستورات زبان اسمبلی، توجه و دقت نیاز دارید. بنابراین، در واقعیت، عمدتا برنامه ها به زبان اسمبلی نوشته می شوند، که باید کار موثر با سخت افزار را تضمین کند. همچنین قسمت هایی از برنامه که از نظر زمان اجرا یا مصرف حافظه حیاتی هستند به زبان اسمبلی نوشته می شوند. پس از آن، آنها به عنوان برنامه های فرعی قالب بندی شده و با کد زبان سطح بالا ترکیب می شوند.

1. ثبت می کند

ثبات ها مکان های حافظه خاصی هستند که مستقیماً در پردازنده قرار دارند. کار با ثبات ها بسیار سریعتر از کار با سلول های حافظه است؛ بنابراین، ثبات ها هم در برنامه های زبان اسمبلی و هم توسط کامپایلرهای زبان سطح بالا به طور فعال استفاده می شوند.

ثبت را می توان به تقسیم کرد ثبت های عمومی,نشانگر فرمان,ثبت پرچم و ثبت بخش.

1.1. ثبت های همه منظوره

به ثبات های عمومی گروهی از 8 ثبات هستند که می توانند در برنامه های زبان اسمبلی استفاده شوند. تمام ثبات ها 32 بیت هستند و می توان آنها را به 2 قسمت یا بیشتر تقسیم کرد.

همانطور که در شکل مشاهده می کنید، رجیسترهای ESI، EDI، ESP و EBP به شما امکان می دهند به ترتیب با نام های SI، DI، SP و BP به 16 بیت پایینی دسترسی داشته باشید، در حالی که رجیسترهای EAX، EBX، ECX و EDX به شما این امکان را می دهند. برای دسترسی به 16 بیت پایین (با نام های AX، BX، CX و DX)، و به دو بایت کم اهمیت به طور جداگانه (با نام های AH / AL، BH / BL، CH / CL و

نام رجیسترها از هدف آنها ناشی می شود:

EAX / AX / AH / AL (رجیستر انباشته) - انباشته.

EBX / BX / BH / BL (رجیستر پایه) - ثبت پایه؛

ECX / CX / CH / CL (ثبت شمارنده) - شمارنده؛

EDX / DX / DH / DL (ثبت نام داده) - ثبت داده؛

ESI / SI (ثبت فهرست منبع) - فهرست منبع؛

EDI / DI (ثبت فهرست مقصد) - فهرست گیرنده (گیرنده)؛

ESP / SP (ثبت نشانگر پشته) - ثبت اشاره گر پشته؛

EBP / BP (ثبت نشانگر پایه) - ثبت اشاره گر پایه قاب پشته.

علیرغم تخصص موجود، همه رجیسترها در هر عملیات ماشینی قابل استفاده هستند. با این حال، باید این واقعیت را در نظر گرفت که برخی از دستورات فقط با ثبات های خاصی کار می کنند. به عنوان مثال، دستورالعمل های ضرب و تقسیم از ثبات های EAX و EDX برای ذخیره داده های اصلی و نتیجه عملیات استفاده می کنند. دستورالعمل های کنترل چرخه از ثبات ECX به عنوان شمارنده چرخه استفاده می کند.

نکته ظریف دیگر استفاده از ثبات ها به عنوان پایه است، یعنی. آدرس های ذخیره سازی رم هر رجیستر را می توان به عنوان ثبات پایه استفاده کرد، اما استفاده از ثبات های EBX، ESI، EDI یا EBP مطلوب است. در این مورد، اندازه دستورالعمل ماشین معمولا کوچکتر است.

متأسفانه تعداد رجیسترها به طرز فاجعه باری کم است و اغلب یافتن بهترین راه برای استفاده از آنها دشوار است.

1.2. اشاره گر فرمان

ثبت EIP ( نشانگر فرمان) شامل offset دستور بعدی است که باید اجرا شود. این رجیستر مستقیماً در دسترس برنامه نویس نیست، اما بارگذاری و تغییر مقدار آن توسط دستورات کنترلی مختلفی انجام می شود که شامل دستوراتی برای پرش های شرطی و بدون شرط، فراخوانی رویه ها و بازگشت از رویه ها می باشد.

1.3. ثبت پرچم

پرچم بیتی است که در صورت رعایت یک شرط، مقدار 1 ("پرچم تنظیم شده است") و در غیر این صورت مقدار 0 ("پرچم پاک شد") می گیرد. پردازنده دارای یک ثبت پرچم است که حاوی مجموعه ای از پرچم ها است که وضعیت فعلی پردازنده را منعکس می کند.

تعیین

نام

پرچم حمل شد

رزرو شده است

پرچم برابری

رزرو شده است

پرچم حمل کمکی

یاور

رزرو شده است

پرچم صفر

پرچم را امضا کنید

پرچم ردیاب

وقفه فعال کردن پرچم

پرچم رزولوشن

پرچم هدایت می شود

پرچم رپو

سطح امتیاز I/O

سطح در

پرچم تو در تو

رزرو شده است

پرچم زنده شد

حالت مجازی-8086

حالت مجازی

شما را بررسی کنید

پرچم وقفه مجازی

مجازی

وقفه مجازی در انتظار

در انتظار

در حال بررسی برای

رزرو شده است

پرچم‌های CF، DF و IF را می‌توان مستقیماً در رجیستر پرچم‌ها با استفاده از دستورالعمل‌های خاص تغییر داد (به عنوان مثال، CLD برای پاک کردن پرچم جهت)، اما هیچ دستورالعملی وجود ندارد که به شما امکان دسترسی به ثبت پرچم را به عنوان یک ثبات معمولی بدهد. با این حال، می توانید پس انداز کنید

پرچم‌ها روی پشته یا رجیستر AH ثبت می‌شوند و با استفاده از دستورالعمل‌های LAHF، SAHF، PUSHF، PUSHFD، POPF و POPFD، ثبت پرچم‌ها را از آنها بازیابی می‌کنند.

1.3.1. پرچم های وضعیت

پرچم های وضعیت (بیت های 0، 2، 4، 6، 7 و 11) نتیجه اجرای دستورات حسابی مانند ADD، SUB، MUL، DIV را منعکس می کنند.

پرچم حمل CF هنگام انتقال از MSB / قرض به MSB تنظیم می شود و وجود سرریز در حساب عدد صحیح بدون علامت را نشان می دهد. همچنین در محاسبات طولانی استفاده می شود.

پرچم برابری PF در صورتی تنظیم می‌شود که بایت کم‌اهمیت نتیجه حاوی عدد زوج یک بیت باشد. در ابتدا، این پرچم برای استفاده در برنامه های ارتباطی در نظر گرفته شده بود: هنگام انتقال داده ها از طریق خطوط ارتباطی، یک بیت برابری نیز می تواند برای کنترل منتقل شود و دستورالعمل های بررسی پرچم برابری بررسی یکپارچگی داده ها را آسان تر می کند.

پرچم حامل کمکی AF برای انجام یک بیت تنظیم شده است 3 نتیجه / وام در 3 بیت نتیجه این پرچم برای استفاده در هدف گذاری شده است اعشاری دودویی (باینری کد اعشاری، BCD) حسابی.

اگر نتیجه صفر باشد، پرچم صفر ZF تنظیم می شود.

پرچم علامت SF برابر است با مقدار مهم ترین بیت نتیجه، که بیت علامت در محاسبات علامت دار است.

پرچم سرریز OF در صورتی تنظیم می شود که نتیجه عدد صحیح بیش از حد طولانی باشد که در عملوند هدف (رجیستر یا مکان حافظه) قرار بگیرد. این پرچم وجود سرریز در حساب عدد صحیح امضا شده را نشان می دهد.

از میان پرچم‌های فهرست شده، فقط پرچم CF را می‌توان مستقیماً با استفاده از دستورالعمل‌های STC، CLC و CMC تغییر داد.

پرچم‌های وضعیت به دستورالعمل‌های حسابی یکسان اجازه می‌دهند تا سه نوع نتیجه متفاوت تولید کنند: عدد صحیح بدون علامت، علامت‌دار، و عدد صحیح باینری-اعشاری (BCD). اگر نتیجه یک عدد بدون علامت در نظر گرفته شود، پرچم CF وضعیت سرریز را نشان می دهد (حمل یا قرض گرفتن)، برای نتیجه امضا شده، حمل یا قرض پرچم OF و برای نتیجه BCD، حمل / قرض AF را نشان می دهد. پرچم. پرچم SF نشانه یک نتیجه امضا شده را منعکس می کند، پرچم ZF هم یک نتیجه بدون علامت و هم یک نتیجه تهی امضا شده را منعکس می کند.

در محاسبات اعداد صحیح بلند، پرچم CF همراه با دستورات جمع و حمل (ADC) و تفریق و قرض گرفتن (SBB) برای انتشار یک انتقال یا قرض گرفتن از یک بیت محاسبه‌شده از یک عدد طولانی به دیگری استفاده می‌شود.

دستورالعمل ها

مشروط

انتقال Jcc (انتقال

شرط سی سی)، SETcc (مجموعه

معنی

بایت نتیجه

وابستگی ها

شرایط cc)، LOOPcc (سازمان

و CMOVcc (مشروط

کپی 🀄)

استفاده کنید

یکی یا بیشتر

پرچم های وضعیت برای بررسی وضعیت. برای مثال، یک دستور پرش JLE (پرش اگر کمتر یا مساوی باشد) شرط "ZF = 1 یا SF ≠ OF" را آزمایش می کند.

پرچم PF برای سازگاری با سایر معماری های ریزپردازنده معرفی شد و به ندرت برای هدف مورد نظر خود استفاده می شود. استفاده از آن همراه با سایر پرچم‌های وضعیت در محاسبات ممیز شناور رایج‌تر است: دستورالعمل‌های مقایسه (FCOM، FCOMP، و غیره) در پردازشگر ریاضی، پرچم‌های شرط C0، C1، C2 و C3 را در آن تنظیم می‌کنند و این پرچم‌ها می توان برای ثبت پرچم ها کپی کرد. برای انجام این کار، توصیه می شود از دستور FSTSW AX برای ذخیره کلمه وضعیت همپردازنده در ثبات AX و دستورالعمل SAHF برای کپی بعدی محتویات ثبات AH در 8 بیت پایینی رجیستر پرچم ها با C0 استفاده کنید. با وارد کردن پرچم CF، C2 به PF و C3 به ZF. پرچم C2 برای مثال در مورد آرگومان های غیرقابل مقایسه (NaN یا قالب پشتیبانی نشده) در عبارت مقایسه FUCOM تنظیم می شود.

1.3.2. پرچم کنترل

پرچم جهت DF (بیت 10 در ثبت پرچم ها) دستورالعمل های رشته ای (MOVS، CMPS، SCAS، LODS و STOS) را کنترل می کند - تنظیم پرچم آدرس ها را کاهش می دهد (خطوط فرآیند از آدرس های بالا به آدرس های پایین)، صفر کردن باعث افزایش آدرس ها می شود. دستورات STD و CLD به ترتیب پرچم DF را تنظیم و پاک می کنند.

1.3.3. پرچم های سیستم و فیلد IOPL

پرچم های سیستم و میدان IOPL محیط عملیاتی را کنترل می کنند و برای برنامه های کاربردی در نظر گرفته نشده اند.

وقفه فعال کردن پرچم IF - با پاک کردن این پرچم، پاسخ به درخواست‌های وقفه پوشانده شده غیرفعال می‌شود.

پرچم ردیابی TF - تنظیم این پرچم اشکال زدایی گام به گام را پس از هر اجرا فعال می کند

دستورالعمل ها، برنامه قطع می شود و یک کنترل کننده وقفه خاص فراخوانی می شود.

فیلد IOPL سطح اولویت I/O برنامه یا وظیفه اجرایی را نشان می دهد: برای اینکه یک برنامه یا وظیفه دستورات I/O را اجرا کند یا پرچم IF را تغییر دهد، سطح اولویت فعلی آن (CPL) باید ≤ IOPL باشد.

پرچم تودرتو وظیفه NT - این پرچم زمانی تنظیم می شود که وظیفه فعلی در یک کار قطع شده دیگر "تودرتو" شده باشد و بخش وضعیت TSS وظیفه فعلی بازخوردی را به TSS کار قبلی ارائه می دهد. پرچم NT توسط یک دستورالعمل IRET بررسی می شود تا مشخص شود که نوع بازگشتی بین وظیفه است یا درون وظیفه.

پرچم رزومه RF برای پنهان کردن خطاهای اشکال زدایی استفاده می شود.

VM - تنظیم این پرچم در حالت محافظت شده باعث تغییر حالت مجازی 8086 می شود.

پرچم بررسی تراز AC - تنظیم این پرچم همراه با بیت AM در رجیستر CR0 کنترل تراز عملوند را در حین دسترسی به حافظه امکان پذیر می کند: دسترسی به یک عملوند بدون تراز یک استثنا را ایجاد می کند.

VIF - کپی مجازی پرچم IF. در ارتباط با پرچم VIP استفاده می شود.

VIP - تنظیم برای نشان دادن وجود یک وقفه معلق.

ID - امکان تغییر برنامه‌نویسی این پرچم در ثبت پرچم نشان‌دهنده پشتیبانی از دستورالعمل CPUID است.

1.4. ثبت بخش ها

این پردازنده دارای 6 به اصطلاح ثبات بخش است: CS، DS، SS، ES، FS و GS. وجود آنها به دلیل ویژگی های سازماندهی و استفاده از رم است.

رجیسترهای 16 بیتی فقط می توانند 64 کیلوبایت رم را آدرس دهی کنند، که به وضوح برای یک برنامه کمابیش مناسب کافی نیست. بنابراین حافظه در قالب چند سگمنت که 64 کیلوبایت بود به برنامه اختصاص یافت. در این مورد، آدرس های مطلق 20 بیتی بودند، که آدرس دهی 1 مگابایت رم را ممکن می کرد. این سوال مطرح می شود - چگونه آدرس های 20 بیتی را با ثبات های 16 بیتی ذخیره کنیم؟ برای حل این مشکل، آدرس بر اساس افست شکسته شد. مبنا آدرس شروع بخش است و آفست تعداد بایت داخل سگمنت است. محدودیتی روی آدرس ابتدای بخش اعمال شد - باید مضرب 16 باشد. در این مورد، 4 بیت آخر برابر با 0 بود و ذخیره نمی شد، بلکه ضمنی بود. بنابراین، دو بخش 16 بیتی از آدرس به دست آمد. برای گرفتن

از آدرس مطلق، چهار بیت صفر به پایه اضافه شد و مقدار حاصل با یک افست اضافه شد.

ثبت بخش برای ذخیره آدرس ابتدای یک بخش کد (CS - بخش کد)، یک بخش داده (DS - بخش داده) و یک بخش پشته (SS - بخش پشته) استفاده شد. رجیسترهای ES، FS و GS بعدا اضافه شدند. چندین مدل حافظه وجود داشت که هر کدام به معنای تخصیص یک یا چند بخش کد و یک یا چند بخش داده به برنامه بود: کوچک، کوچک، متوسط، فشرده، بزرگ و بزرگ. قراردادهای خاصی برای دستورالعمل‌های زبان اسمبلی وجود داشت: آدرس‌های پرش توسط رجیستر CS بخش‌بندی شدند، دسترسی‌های داده توسط رجیستر DS بخش‌بندی شدند، و تماس‌های پشته‌ای توسط ثبات SS بخش‌بندی شدند. اگر به یک برنامه چندین بخش برای کد یا داده اختصاص داده می شد، برای دسترسی به بخش دیگری باید مقادیر موجود در ثبات های CS و DS تغییر می کرد. گذرگاه های به اصطلاح «نزدیک» و «دور» وجود داشت. اگر دستوری که قرار بود پرش به آن انجام شود در همان بخش بود، برای پرش کافی بود فقط مقدار ثبات IP را تغییر دهید. چنین انتقالی "نزدیک" نامیده شد. اگر دستوری که قرار بود پرش به آن انجام شود در سگمنت دیگری بود، برای پرش باید هم مقدار ثبات CS و هم مقدار ثبات IP را تغییر داد. این انتقال، مسافت طولانی نامیده می‌شد و بیشتر طول کشید.

رجیسترهای 32 بیتی به شما امکان می دهند تا 4 گیگابایت حافظه را آدرس دهی کنید که در حال حاضر برای هر برنامه کافی است. ویندوز هر برنامه Win32 را در یک فضای مجازی مجزا اجرا می کند. این بدان معناست که هر برنامه Win32 دارای فضای آدرس 4 گیگابایتی خواهد بود، اما به این معنا نیست که هر برنامه دارای 4 گیگابایت حافظه فیزیکی است، بلکه فقط می تواند به هر آدرسی در این محدوده دسترسی داشته باشد. و ویندوز هر کاری را که برای حافظه ای که برنامه به آن دسترسی دارد انجام می دهد. البته برنامه باید قوانین تعیین شده را رعایت کند

ویندوز، در غیر این صورت یک خطای General Protection Fault رخ می دهد.

در معماری Win32، نیازی به تفکیک آدرس به پایه و افست و نیاز به مدل های حافظه وجود نداشت. در 32-

متفاوت استفاده می شود 1. قبلاً لازم بود که بخش‌های جداگانه برنامه را با یک یا آن رجیستر سگمنت مرتبط کنیم و هنگام انتقال به بخش داده دیگری، رجیستر DS را ذخیره یا بازیابی کنیم، یا داده‌ها را صریحاً در رجیستر دیگری تقسیم کنیم. با معماری 32 بیتی، دیگر نیازی به این کار نیست و در ساده ترین حالت، می توانید رجیسترهای سگمنت را فراموش کنید.

1.5. با استفاده از پشته

هر برنامه دارای یک ناحیه از حافظه به نام پشته است. پشته برای ارسال پارامترها به رویه ها و ذخیره داده های محلی برای رویه ها استفاده می شود. همانطور که می دانید، پشته منطقه ای از حافظه است که هنگام کار با آن باید قوانین خاصی رعایت شود، یعنی: داده هایی که ابتدا وارد پشته شده اند، آخرین بار از آنجا بازیابی می شوند. از سوی دیگر، اگر مقداری حافظه به برنامه اختصاص داده شود، محدودیت فیزیکی برای خواندن و نوشتن وجود ندارد. چگونه این دو اصل متضاد با هم تناسب دارند؟

فرض کنید یک تابع f1 داریم که تابع f2 را فراخوانی می کند و تابع f2 به نوبه خود تابع f3 را فراخوانی می کند. هنگامی که تابع f1 فراخوانی می شود، یک مکان مشخص در پشته برای داده های محلی به آن اختصاص داده می شود. این فضا با کم کردن مقداری برابر با اندازه حافظه مورد نیاز از ثبات ESP تخصیص می یابد. حداقل اندازه حافظه اختصاص داده شده 4 بایت است، یعنی. حتی اگر روش به 1 بایت نیاز داشته باشد، باید 4 بایت طول بکشد.

تابع f1 برخی اقدامات را انجام می دهد و سپس فراخوانی می کند

تابع f2 تابع f3 را فراخوانی می کند که همچنین فضایی را در پشته اختصاص می دهد. تابع f3 هیچ توابع دیگری را فراخوانی نمی کند و پس از اتمام کار باید با اضافه کردن مقداری که هنگام فراخوانی تابع کم شده است، فضایی را در پشته آزاد کند. اگر تابع f3 مقدار ثبات ESP را بازیابی نکند، تابع f2 که به کار خود ادامه می دهد، به داده های خود دسترسی نخواهد داشت، زیرا او در حال جستجو است

که قبل از فراخوانی او بود.

بنابراین، در سطح رویه ها، لازم است قوانین کار با پشته را دنبال کنید - رویه ای که آخرین فضای روی پشته را اشغال کرده است، ابتدا باید آن را آزاد کند. اگر این قانون رعایت نشود، برنامه به درستی کار نخواهد کرد. اما هر رویه می تواند به صورت دلخواه به ناحیه پشته خود دسترسی داشته باشد. اگر ما مجبور به پیروی از قوانین کار با پشته در داخل هر رویه باشیم، باید داده ها را از پشته به قسمت حافظه دیگری منتقل می کنیم و این امر بسیار ناخوشایند خواهد بود و اجرای برنامه را به شدت کاهش می دهد.

هر برنامه دارای یک ناحیه داده است که متغیرهای سراسری در آن قرار دارند. چرا داده های محلی در پشته ذخیره می شود؟ این کار برای کاهش حجم حافظه اشغال شده توسط برنامه انجام می شود. اگر برنامه باشد هموارهچندین رویه را فراخوانی کنید، سپس در هر لحظه از زمان فضا فقط به داده های یک رویه اختصاص داده می شود، زیرا پشته اشغال شده و آزاد می شود. منطقه داده در تمام مدتی که برنامه در حال اجرا است وجود دارد. اگر داده های محلی در ناحیه داده قرار می گرفتند، لازم بود برای همه رویه های برنامه فضا برای داده های محلی اختصاص داده شود.

داده های محلی به طور خودکار مقداردهی اولیه نمی شوند. اگر در مثال بالا تابع f2 بعد از تابع f3 تابع f4 را فراخوانی کند، تابع f4 جایی را در پشته ای که قبلاً توسط تابع f3 اشغال شده بود اشغال می کند، بنابراین تابع f4 تابع f3 را به ارث می برد. بنابراین، هر رویه باید مراقب مقداردهی اولیه داده های محلی خود باشد.

2. مفاهیم اولیه زبان اسمبلی

2.1. شناسه ها

مفهوم شناسه در زبان اسمبلی هیچ تفاوتی با مفهوم شناسه در زبان های دیگر ندارد. می توانید از حروف لاتین، اعداد و علائم _ استفاده کنید. ? @ $، که نقطه فقط می تواند اولین کاراکتر یک شناسه باشد. حروف بزرگ و کوچک معادل در نظر گرفته می شوند.

2.2. تمام اعداد

V در برنامه‌های زبان اسمبلی، اعداد صحیح را می‌توان به‌صورت باینری، هشت‌گانه، اعشاری و هگزادسیمال نوشت. برای تنظیم سیستم اعداد در انتهای یک عدد

بعد از سال‌ها انجام کاری بدون ضربه زدن به آن، تصمیم گرفتم به اصول اولیه برگردم. به برنامه نویسی باز هم، با توجه به انبوه «پیشرفت‌های مدرن» در این زمینه، تعیین اینکه واقعاً چه چیزی کم است، چه چیزی را برای خوشایند و مفید کردن آن باید انجام داد، دشوار بود. پس از تلاش کمی برای بسیاری از چیزها، تصمیم گرفتم به جایی که از اولین روزهای آشنایی من با یک کامپیوتر (حتی با یک کپی از خلقت سر سینکلر) کشیده شده بودم - به برنامه نویسی به زبان اسمبلی بازگردم. در واقع، زمانی من اسمبلر را به خوبی می شناختم (در این مورد، من در مورد x86 صحبت می کنم)، اما برای تقریبا 15 سال چیزی در آن ننوشتم. بنابراین، این نوعی بازگشت «پسر ولخرج» است.
اما اینجا اولین ناامیدی در انتظار بود. کتاب‌ها، راهنماها و سایر کتاب‌های مرجع در مورد اسمبلر که در اینترنت یافت می‌شوند، با تأسف عمیق من، حاوی حداقل اطلاعات در مورد نحوه برنامه‌نویسی در اسمبلر، چرایی این کار و آنچه که می‌دهد، هستند.

نمونه ای از یک منطقه دیگر

اگر بوکس را به عنوان مثال در نظر بگیریم، پس همه این دستورالعمل ها نحوه اجرای پانچ، حرکت در حالت ایستاده روی زمین را آموزش می دهند، اما آنچه بوکس انجام می دهد مطلقاً وجود ندارد - بوکس، و نه "ضربه قانونی". یعنی کار ترکیبی، ویژگی های استفاده از رینگ، اقدامات دفاعی، ساختار تاکتیکی نبرد و علاوه بر این، استراتژی نبرد اصلاً در نظر گرفته نمی شود. آنها به مردی یاد دادند که "گلابی" را بزند و بلافاصله وارد رینگ شود. این از اساس اشتباه است. اما تقریباً تمام "کتاب های درسی" و "راهنماهای" برنامه نویسی در اسمبلی به این صورت است.


با این حال، کتاب های عادی باید باشد، به احتمال زیاد در زیر کوه "سرباره" من فقط آنها را پیدا نکردم. بنابراین، قبل از پر کردن دانش با توصیف جهانی معماری، یادگاری و انواع ترفندها "چگونه یک انجیر را از دو انگشت کور کنیم"، اجازه دهید به موضوع برنامه نویسی در مونتاژ از دیدگاه "ایدئولوژیک" بپردازیم.

ایدیل؟

یک نکته کوچک، در ادامه متن از طبقه بندی استفاده خواهد شد که با طبقه بندی رایج فعلی متفاوت است. با این حال، این دلیلی برای "اختلاف در مورد رنگ حقیقت" نیست، فقط در این شکل می توان دیدگاه نویسنده در مورد برنامه نویسی را توضیح داد.

بنابراین، امروز، به نظر می رسد، عصر شادی برای برنامه نویسان فرا رسیده است. انتخاب عظیمی از بودجه برای همه مناسبت ها و آرزوها. میلیون ها "چارچوب" / "الگو" / "الگو" / "کتابخانه" و هزاران ابزار برای "تسهیل" برنامه نویسی، صدها زبان و گویش، ده ها روش و رویکردهای مختلف برای برنامه نویسی وجود دارد. آن را بگیر - من نمی خواهم. اما "گرفته" نیست. و نکته در اعتقادات مذهبی نیست، بلکه در این است که همه اینها تلاشی برای خوردن چیزی بی مزه به نظر می رسد. البته با میل و پشتکار می توانید خود را با این امر وفق دهید. اما، با بازگشت به برنامه نویسی، در بیشتر موارد پیشنهادی، زیبایی فنی قابل مشاهده نیست - فقط تعداد زیادی "عصا" قابل مشاهده است. در نتیجه، وقتی از این "دستاوردها" استفاده می شود، به جای مناظر جذاب، به جای مناظر جذاب، یک "انتزاع" جامد یا چاپ های محبوب از زیر "برس هنرمندان" بیرون می آید - اگر خوش شانس باشید. آیا اکثر برنامه نویسان در سطح ژنتیکی اینگونه افراد متوسط، نادان و مشکل دارند؟ نه من اینطور فکر نمیکنم. پس دلیلش چیست؟
امروزه ایده ها و روش های زیادی برای برنامه نویسی وجود دارد. بیایید "شیک ترین" آنها را در نظر بگیریم.

  • برنامه نویسی ضروری - در این رویکرد، برنامه نویس دنباله ای از اقدامات را تنظیم می کند که منجر به حل مشکل می شود. این بر اساس تقسیم برنامه به بخش هایی است که عملیات منطقی مستقل (ماژول ها، توابع، رویه ها) را انجام می دهند. اما بر خلاف روش تایپ شده (به زیر مراجعه کنید)، یک ویژگی مهم در اینجا وجود دارد - عدم وجود متغیرهای "تایپ". به عبارت دیگر، مفهوم «نوع متغیر» وجود ندارد، در عوض از این درک استفاده می‌شود که مقادیر همان متغیر می‌تواند نوع متفاوتی داشته باشد. نمایندگان واضح این رویکرد Basic، REXX، MUMPS هستند.
  • برنامه نویسی تایپ شده تغییری در برنامه نویسی ضروری است، زمانی که برنامه نویس و سیستم مقادیر احتمالی متغیرها را محدود می کنند. معروف ترین زبان ها پاسکال، سی.
  • برنامه نویسی تابعی یک روش ریاضی تر برای حل یک مسئله است، زمانی که راه حل شامل "ساخت" سلسله مراتبی از توابع (و بر این اساس، ایجاد توابع گمشده) است که منجر به حل مسئله می شود. به عنوان مثال: Lisp، Forth.
  • برنامه نویسی خودکار رویکردی است که در آن یک برنامه نویس مدل/شبکه ​​ای متشکل از اشیا/عناصر اجرایی مبادله پیام می سازد که هم «وضعیت» درونی خود را تغییر می دهد/ذخیره می کند و هم قادر به تعامل با دنیای خارج است. به عبارت دیگر، این همان چیزی است که معمولاً به عنوان "برنامه نویسی شی" (نه شی گرا) شناخته می شود. این روش برنامه نویسی در اسمال تاک معرفی شده است.
اما در مورد بسیاری از زبان های دیگر چطور؟ به عنوان یک قاعده، اینها قبلا "جهش یافته" هستند. به عنوان مثال، ترکیبی از رویکردهای تایپ شده و خودکار منجر به "برنامه نویسی شی گرا" شد.

همانطور که می بینید، هر یک از رویکردها (حتی بدون در نظر گرفتن محدودیت های پیاده سازی های خاص) محدودیت های خود را بر خود تکنیک برنامه نویسی تحمیل می کند. اما غیر از این نمی تواند باشد. متأسفانه، این محدودیت ها اغلب به طور مصنوعی برای «پاک نگه داشتن ایده» ایجاد می شوند. در نتیجه، برنامه نویس باید راه حل اولیه پیدا شده را به شکلی که به نوعی با ایدئولوژی زبان مورد استفاده یا «الگوی» استفاده شده مطابقت دارد، «منحرف» کند. این حتی بدون در نظر گرفتن تکنیک ها و روش های جدید طراحی و توسعه است.

به نظر می رسد در حین برنامه نویسی به زبان اسمبلی، ما آزادیم که هر کاری را به روشی که می خواهیم و سخت افزار به ما اجازه می دهد انجام دهیم. اما به محض اینکه بخواهیم از یک "درایور عمومی" برای هر نوع تجهیزاتی استفاده کنیم، مجبوریم آزادی "خلاقیت" را برای رویکردها و روش های تجویز شده (استاندارد) استفاده از درایور تغییر دهیم. به محض اینکه به فرصتی نیاز داشتیم تا از پیشرفت‌های سایر همکاران استفاده کنیم یا به آنها این فرصت را بدهیم که با ثمره کار خود نیز همین کار را انجام دهند، مجبوریم آزادی انتخاب تعامل بین بخش‌های برنامه را برای برخی توافق‌ها تغییر دهیم / راه های استاندارد

بنابراین، "آزادی" که مردم اغلب برای آن به مونتاژ می شتابند اغلب به یک "افسانه" تبدیل می شود. و این (درک محدودیت ها و راه های سازماندهی آنها) به نظر من باید بیشتر مورد توجه قرار گیرد. برنامه نویس باید دلیل محدودیت های معرفی شده را بداند و که اسمبلر را از بسیاری از زبان های سطح بالا متمایز می کند، بتواند در صورت نیاز آنها را تغییر دهد. با این حال، اکنون برنامه نویس اسمبلر مجبور است محدودیت های اعمال شده توسط زبان های سطح بالا را تحمل کند، زیرا هیچ "هویج" در دسترس برنامه نویسان در آنها وجود ندارد. از یک طرف، سیستم عامل ها بسیاری از توابع از قبل پیاده سازی شده را ارائه می دهند، کتابخانه های آماده و بسیاری موارد دیگر وجود دارد. اما روش های استفاده از آنها، همانطور که بود، بدون در نظر گرفتن فراخوانی آنها از برنامه های نوشته شده در اسمبلر یا حتی به طور کلی بر خلاف منطق برنامه نویسی برای معماری x86 پیاده سازی می شود. در نتیجه، امروزه برنامه نویسی به زبان اسمبلی با فراخوانی توابع سیستم عامل یا کتابخانه های خارجی زبان های سطح بالا، «ترس» و «وحشت» است.

هر چه بیشتر به جنگل بروید، ضخیم تر است

بنابراین، متوجه شدیم که اگرچه اسمبلر بسیار ساده است، اما باید بتوانید از آن استفاده کنید. و سازگاری اصلی نیاز به تعامل با محیط زمان اجرا است که برنامه ما در آن راه اندازی می شود. اگر برنامه نویسان در زبان های سطح بالا قبلاً به کتابخانه ها، توابع، برنامه های فرعی لازم برای بسیاری از موارد دسترسی داشته باشند و به روش های تعامل با دنیای خارج به شکلی مطابق با ایده زبان دسترسی داشته باشند، پس برنامه نویس اسمبلر باید از میان انبوه انواع موانع نصب شده در فضای خالی عبور کند. وقتی به زبان‌های سطح بالا در حین کامپایل نگاه می‌کنید، این تصور را به دست می‌آورید که کسانی که کامپایلر را نوشته‌اند، نمی‌دانند پردازنده‌ای با معماری x86 چگونه کار می‌کند، "یا یکی از دو" (q).

پس بیایید به ترتیب شروع کنیم. برنامه نویسی قبل از هر چیز مهندسی است، یعنی خلاقیت علمی با هدف حل کارآمد (از نظر قابلیت اطمینان، استفاده از منابع موجود، زمان اجرا و سهولت استفاده) مسائل عملی. و در قلب هر مهندسی یک رویکرد سیستمی است. یعنی هیچ راه حلی را نمی توان نوعی جعبه سیاه «غیرقابل تفکیک» دانست که در خلاء کامل و ایده آل کار می کند.

نمونه ای دیگر از یک منطقه متفاوت

تولید کامیون در ایالات متحده را می توان به عنوان نمونه بارز رویکرد سیستماتیک ذکر کرد. در این مورد، سازنده کامیون صرفاً سازنده قاب و کابین + مونتاژکننده سازنده است. بقیه موارد (موتور، گیربکس، سیستم تعلیق، تجهیزات الکتریکی و غیره) بر اساس خواسته مشتری گرفته می شود. یکی از مشتریان می خواست برای خود یک کنورث با موتوری از دیترویت دیزل، گیربکس دستی فولر، سیستم تعلیق فنر برگ از دانا تهیه کند - لطفا. یکی از دوستان این مشتری به همان مدل Kenworth نیاز داشت، اما با موتور بومی Paccar، گیربکس اتوماتیک آلیسون و سیستم تعلیق بادی از یک سازنده دیگر - آسان! و این کاری است که تمام کامیون سازان در ایالات متحده انجام می دهند. یعنی کامیون سیستمی است که در آن هر ماژول را می توان با یک ماژول دیگر با همان هدف جایگزین کرد و به طور یکپارچه به ماژول های موجود متصل کرد. علاوه بر این، روش اتصال ماژول ها با حداکثر تطبیق پذیری موجود و راحتی برای گسترش بیشتر عملکرد ساخته شده است. این همان چیزی است که مهندس باید برای آن تلاش کند.

متأسفانه ما باید با آنچه که داریم زندگی کنیم، اما در آینده باید از این امر اجتناب شود. بنابراین، یک برنامه در واقع مجموعه‌ای از ماژول‌ها است (مهم نیست چگونه نامیده می‌شوند و چگونه "رفتار" دارند)، با مونتاژ کردن آنها به یک راه حل برای کار در دست می‌رسیم. برای کارایی، بسیار مطلوب است که این ماژول ها قابل استفاده مجدد باشند. و نه تنها به هر قیمتی از آن استفاده کنید، بلکه از آن به روشی راحت استفاده کنید. و در اینجا "سورپرایز" ناخوشایند دیگری در انتظار ما است. اکثر زبان های سطح بالا بر روی واحدهای ساختاری مانند "عملکرد" ​​و "روش" کار می کنند. و به عنوان روشی برای مقابله با آنها از "گذر پارامتر" استفاده می شود. این کاملاً منطقی است و هیچ سؤالی در اینجا مطرح نمی شود. اما مثل همیشه، "مهم نیست آنچه انجام می شود مهم است - نحوه انجام آن مهم است" (ج). و اینجا نامفهوم ترین شروع می شود. امروزه 3 روش متداول برای سازماندهی انتقال پارامترها وجود دارد: cdecl, stdcall, تماس سریع... بنابراین، هیچ یک از این روش ها برای x86 "بومی" نیستند. علاوه بر این، همه آنها از نقطه نظر گسترش عملکرد زیربرنامه های نامیده شده دارای نقص هستند. یعنی با افزایش تعداد پارامترهای ارسال شده، مجبور می شویم تمام نقاط فراخوانی این تابع/زیر روال را تغییر دهیم یا یک زیربرنامه جدید با عملکرد مشابه تولید کنیم که به روشی کمی متفاوت فراخوانی می شود.

روش‌های فوق برای انتقال پارامترها روی پردازنده‌هایی با 2 پشته مجزا (پشته داده و آدرس / پشته کنترل) و دستورالعمل‌های دستکاری پشته پیشرفته (حداقل دسترسی فهرست به عناصر پشته) نسبتاً خوب عمل می‌کنند. اما هنگام برنامه نویسی در x86، ابتدا باید هنگام ارسال / دریافت پارامترها منحرف شوید و سپس به یاد داشته باشید که آنها را به صورت "ساختاری" از پشته حذف کنید. در طول راه، تلاش برای حدس زدن / محاسبه حداکثر عمق پشته. به یاد بیاورید که x86 (حالت 16/32 بیت) پردازنده ای است که دارای:

  • رجیسترهای تخصصی (RON ها رجیسترهای همه منظوره هستند - به این ترتیب وجود ندارند: یعنی نمی توانیم با یک دستور محتویات رجیستر GS را در مقدار EDI ضرب کنیم و نتیجه را در جفت EDX: ECX بدست آوریم، یا مقدار را تقسیم کنیم. از EDI: جفت رجیستر ESI به ثبت محتویات EAX؛
  • تعداد کمی ثبت نام
  • یک پشته؛
  • مکان حافظه هیچ اطلاعاتی در مورد نوع مقدار ذخیره شده در آنجا نمی دهد.
به عبارت دیگر، تکنیک های برنامه نویسی مورد استفاده برای پردازنده هایی با یک فایل ثبت بزرگ، پشتیبانی از چندین پشته مستقل و غیره. بیشتر برای برنامه نویسی x86 قابل استفاده نیست.

ویژگی بعدی تعامل با ماژول های آماده نوشته شده به «زبان های سطح بالا» «مبارزه با انواع متغیرها» است. از یک طرف، دلیل ظاهر انواع متغیرها واضح است - برنامه نویس می داند که چه مقادیری در زیربرنامه / ماژول خود استفاده می شود. بر این اساس، کاملاً منطقی به نظر می رسد که با تنظیم نوع مقادیر متغیر، با قرار دادن کنترل انواع / حدود مقادیر بر روی مترجم زبان، نوشتن برنامه را "ساده" کنیم. اما حتی در آن زمان نوزاد را با آب بیرون انداختند. زیرا هر برنامه ای نه برای تولید اسب های کروی در خلاء، بلکه برای کار عملی با داده های کاربر نوشته شده است. یعنی نقض آشکار رویکرد سیستمی - گویی که توسعه دهندگان زبان های سطح بالا سیستم های خود را بدون در نظر گرفتن تعامل با دنیای خارج در نظر می گیرند. در نتیجه، هنگام برنامه‌نویسی به زبان تایپ شده، توسعه‌دهنده باید همه انواع داده‌های ورودی «نادرست» ممکن را پیش‌بینی کند و به دنبال راه‌هایی برای رفع ابهامات باشد. و اینجاست که سیستم‌های هیولایی برای پشتیبانی از عبارات منظم، مدیریت استثنا، امضای روش / رویه برای انواع مقادیر مختلف و سایر تولیدات عصا وارد بازی می‌شوند.

همانطور که در بالا ذکر شد، برای معماری x86، خود مقداری که در یک مکان حافظه ذخیره می شود، هیچ نوع خاصی ندارد. برنامه نویس زبان اسمبلی ممتاز است و یک مسئولیتبرای تعیین نحوه رسیدگی به این ارزش. و نحوه تعیین نوع ارزش و نحوه پردازش آن - گزینه های زیادی برای انتخاب وجود دارد. اما، اجازه دهید دوباره تأکید کنیم، همه آنها فقط به مقادیر دریافت شده از کاربر مربوط می شوند. همانطور که توسعه دهندگان زبان های تایپ شده به درستی اشاره کردند، انواع مقدار متغیرهای داخلی و سرویس تقریباً همیشه از قبل شناخته شده است.

به نظر می رسد که این دلیل (انتقال انحرافی پارامترها به ماژول های نوشته شده در زبان های سطح بالا و نیاز به نظارت دقیق بر انواع پارامترهای ارسال شده به همان ماژول ها) اصلی ترین دلیل است که به همین دلیل برنامه نویسی در زبان اسمبلی به طور غیرمنطقی دشوار است. . و اکثریت ترجیح می‌دهند جنگل «زبان‌های سطح بالا» را درک کنند تا از آنچه قبلاً توسط دیگران ایجاد شده است استفاده کنند، تا رنج بکشند، من همان عصاهای «استاندارد» را برای اصلاح کارهایی که آنها انجام نداده‌اند وارد می‌کنم. و یک مترجم اسمبلر کمیاب به نحوی برنامه نویس را از این روال "تخلیه" می کند.

چه باید کرد؟

نتیجه گیری اولیه با در نظر گرفتن 15 پرواز زنگ تفريحدر برنامه نویسی اسمبلی
اول، در مورد ماژول ها یا بخش هایی از یک برنامه. در حالت کلی، ارزش برجسته کردن دو نوع واحد اجرای برنامه در زبان اسمبلی - "عملیات" و "زیر روال" را دارد.
  • "عملیات" ماژولی است که یک عمل "اتمی" را انجام می دهد و برای اجرای آن به پارامترهای زیادی نیاز ندارد (مثلاً عملیات پاک کردن کل صفحه یا عملیات محاسبه میانه یک سری اعداد و غیره). .
  • یک "زیر روال" یک ماژول کاربردی است که برای عملکرد صحیح به پارامترهای ورودی زیادی (بیش از 2x-3x) نیاز دارد.
و در اینجا ارزش ارزیابی تجربه زبان های امری و کاربردی را دارد. آنها 2 ابزار ارزشمند را به ما دادند که ارزش استفاده از آنها را دارند: "ساختار داده" (یا، برای مثال، REXX - متغیرهای ترکیبی / افزوده شده) و "تغییر ناپذیری داده".

پیروی از قاعده تغییرناپذیری - یعنی تغییرناپذیری پارامترهای تصویب شده - نیز مفید است. زیر روال نمی تواند (نباید) مقادیر موجود در ساختار ارسال شده به آن را تغییر دهد و نتیجه یا در ثبات ها (حداکثر پارامترهای 2x-3x) و یا در یک ساختار جدید ایجاد شده برگردانده می شود. بنابراین، در صورت تغییر "فراموش شده" داده ها توسط زیربرنامه ها از نیاز به ساختن کپی از ساختارها خلاص می شویم و می توانیم از یک ساختار از قبل ایجاد شده به طور کامل یا قسمت اصلی آن برای فراخوانی چندین زیربرنامه که با همان / کار می کنند استفاده کنیم. مجموعه ای از پارامترهای مشابه علاوه بر این، عملاً "به طور خودکار" به قانون "عملکردی" بعدی می رسیم - استقلال زمینه داخلی زیر روال ها و عملیات. به عبارت دیگر، به جداسازی حالت / داده ها از روش / زیربرنامه پردازش آنها (بر خلاف مدل خودکار). در موارد برنامه‌نویسی موازی و همچنین استفاده مشترک از یک زیربرنامه، هم از نیاز به تولید بسیاری از زمینه‌های اجرایی و نظارت بر «عدم تقاطع» آن‌ها خلاص می‌شویم و هم از ایجاد بسیاری از نمونه‌های یک زیربرنامه با «حالت‌های» متفاوت. "، در مورد تماس های متعدد آن.

در مورد "انواع" داده ها، می توانید "همه چیز را همانطور که هست" رها کنید، یا همچنین نمی توانید چرخ را دوباره اختراع کنید و از آنچه توسعه دهندگان مترجمان زبان های ضروری برای مدت طولانی استفاده می کنند استفاده کنید. - "شناسه نوع ارزش". یعنی تمام داده‌هایی که از دنیای خارج می‌آیند تجزیه و تحلیل می‌شوند و به هر مقدار دریافتی یک شناسه از نوع پردازش شده (عدد صحیح، ممیز شناور، BCD بسته، کد کاراکتر و غیره) و اندازه فیلد / مقدار اختصاص داده می‌شود. با داشتن این اطلاعات، برنامه نویس از یک سو کاربر را به یک چارچوب باریک غیر ضروری از "قوانین" برای وارد کردن مقادیر وادار نمی کند و از سوی دیگر توانایی انتخاب کارآمدترین روش پردازش داده های کاربر را دارد. در این فرآیند اما، یک بار دیگر تکرار می کنم، این فقط برای کار با داده های کاربر صدق می کند.

اینها ملاحظات کلی برای برنامه نویسی به زبان اسمبلی بود که به طراحی، اشکال زدایی و مدیریت خطا مربوط نمی شد. من امیدوارم که توسعه دهندگان سیستم عامل که آنها را از ابتدا می نویسند (و حتی بیشتر در اسمبلر) چیزی برای فکر کردن داشته باشند و آنها راه هایی را انتخاب کنند (حتی اگر در بالا توضیح داده نشده باشد، اما هر روش دیگری) تا برنامه نویسی در اسمبلر را سیستماتیک تر، راحت تر و راحت تر کنند. لذت بخش است و کورکورانه از گزینه های "کج" دیگران کپی نمی کند.

اسمبلر (Assembly) یک زبان برنامه نویسی است که مفاهیم آن منعکس کننده معماری یک کامپیوتر الکترونیکی است. زبان اسمبلی یک شکل نمادین از نوشتن کد ماشین است که استفاده از آن نوشتن برنامه های ماشین را ساده می کند. زبان های اسمبلی مختلف را می توان برای یک کامپیوتر توسعه داد. برخلاف زبان‌های سطح بالای انتزاع که در آن‌ها بسیاری از مشکلات اجرای الگوریتم‌ها از دید توسعه‌دهندگان پنهان است، زبان اسمبلی ارتباط نزدیکی با مجموعه دستورالعمل‌های ریزپردازنده دارد. برای یک ریزپردازنده ایده آل که مجموعه دستورات آن دقیقاً با زبان برنامه نویسی مطابقت دارد، اسمبلر یک کد ماشین برای هر عبارت در زبان ایجاد می کند. در عمل، ریزپردازنده های واقعی ممکن است برای پیاده سازی یک عبارت واحد در زبان، به چندین دستورالعمل ماشین نیاز داشته باشند.

زبان اسمبلی دسترسی به رجیسترها، مشخص کردن روش‌های آدرس‌دهی و توصیف عملیات بر اساس دستورالعمل‌های پردازنده را فراهم می‌کند. زبان اسمبلی می تواند شامل ابزارهای سطح بالاتری از انتزاع باشد: ماکروهای داخلی و تعریف شده مربوط به چندین دستورالعمل ماشین، انتخاب دستور خودکار بسته به نوع عملوندها، ابزارهای توصیف ساختارهای داده. مزیت اصلی زبان اسمبلی "نزدیک بودن" به پردازنده است که اساس رایانه مورد استفاده برنامه نویس است و عیب اصلی آن تقسیم بسیار کوچک عملیات معمولی است که توسط اکثر کاربران به سختی درک می شود. با این حال، زبان اسمبلی بیش از هر زبان دیگری بازتابی از عملکرد یک کامپیوتر است.

و اگرچه درایورها و سیستم عامل ها اکنون به زبان C نوشته می شوند، اما C با تمام مزایای آن، یک زبان انتزاعی سطح بالا است که ظرافت ها و ظرایف سخت افزاری مختلف را از برنامه نویس پنهان می کند، و اسمبلر یک زبان انتزاعی سطح پایین است که به طور مستقیم منعکس می کند. تمام این ظرافت ها و ظرافت ها.

سه چیز برای استفاده موفقیت آمیز از اسمبلر لازم است:

  • دانش نحو مترجم اسمبلر مورد استفاده (به عنوان مثال، نحو MASM، FASM و GAS متفاوت است)، هدف دستورات زبان اسمبلی (اپراتورهایی که توسط مترجم در هنگام ترجمه کد منبع برنامه پردازش می شوند) ;
  • درک دستورالعمل های ماشینی که توسط پردازنده در حین اجرای برنامه اجرا می شود.
  • توانایی کار با خدمات ارائه شده توسط سیستم عامل - در این مورد به معنای دانش توابع Win32 API است. هنگام کار با زبان های سطح بالا، برنامه نویس اغلب مستقیماً به API سیستم مراجعه نمی کند. او حتی ممکن است از وجود آن آگاه نباشد، زیرا کتابخانه زبان جزئیات خاص سیستم را از برنامه نویس پنهان می کند. به عنوان مثال، در لینوکس، ویندوز، و هر سیستم دیگری در یک برنامه C / C ++، می توانید یک رشته را با استفاده از تابع printf () یا جریان cout به کنسول خروجی دهید، یعنی برای برنامه نویسی که از آن استفاده می کند تفاوتی وجود ندارد. این ابزارها که برنامه تحت چه سیستمی ساخته می شود، اگرچه اجرای این توابع در سیستم های مختلف متفاوت خواهد بود، زیرا API سیستم ها بسیار متفاوت است. اما اگر شخصی به زبان اسمبلی بنویسد، دیگر توابع آماده ای مانند printf () ندارد که در آن به نحوه "ارتباط" با سیستم برای او فکر کرده است و باید خودش این کار را انجام دهد.
در نتیجه، معلوم می شود که نوشتن حتی یک برنامه ساده در اسمبلر به مقدار بسیار زیادی دانش قبلی نیاز دارد - "آستانه ورود" در اینجا بسیار بالاتر از زبان های سطح بالا است.

بهینهشما می توانید برنامه ای را در نظر بگیرید که به درستی و در سریع ترین زمان ممکن کار کند و کمترین حافظه ممکن را اشغال کند. علاوه بر این، خواندن و درک آن آسان است. تغییر آن آسان است؛ ایجاد آن به زمان کمی و هزینه کم نیاز دارد. در حالت ایده‌آل، زبان اسمبلی باید مجموعه‌ای از ویژگی‌ها را داشته باشد که به شما امکان می‌دهد برنامه‌هایی را دریافت کنید که تا حد امکان این ویژگی‌ها را برآورده کنند.

برنامه ها یا قطعات آنها در مواردی که اهمیت حیاتی دارند به زبان اسمبلی نوشته می شوند:

  • مقدار حافظه استفاده شده (برنامه های لودر، نرم افزارهای تعبیه شده، برنامه های میکروکنترلرها و پردازنده های با منابع محدود، ویروس ها، حفاظت های نرم افزاری و غیره)؛
  • سرعت (برنامه های نوشته شده به زبان اسمبلی بسیار سریعتر از برنامه های آنالوگ نوشته شده در زبان های برنامه نویسی با سطح بالایی از انتزاع اجرا می شوند. در نتیجه، برنامه سریعتر شروع به کار می کند، اما قابلیت حمل و تطبیق پذیری را از دست می دهد).
علاوه بر این، دانش زبان اسمبلی درک معماری یک کامپیوتر و عملکرد سخت افزار آن را آسان تر می کند، چیزی که دانش نمی تواند ارائه دهد. زبان های انتزاعی سطح بالا(JAVU). در حال حاضر، اکثر برنامه نویسان برنامه هایی را در محیط های طراحی سریع(Rapid Application Development) زمانی که تمام عناصر طراحی و کنترل لازم با استفاده از اجزای بصری آماده ایجاد می شود. این روند برنامه نویسی را تا حد زیادی ساده می کند. با این حال، ما اغلب مجبوریم با چنین موقعیت هایی روبرو شویم که قدرتمندترین و کارآمدترین عملکرد ماژول های نرم افزاری تنها در صورتی امکان پذیر است که به زبان اسمبلی (درج های اسمبلر) نوشته شده باشند. به ویژه، در هر برنامه ای که با اجرای رویه های چرخه ای تکراری مرتبط باشد، خواه چرخه های محاسبات ریاضی باشد یا خروجی تصاویر گرافیکی، توصیه می شود که وقت گیرترین عملیات را در زیر ماژول های برنامه ریزی شده به زبان اسمبلی گروه بندی کنید. تمام بسته های زبان های برنامه نویسی مدرن با سطح بالایی از انتزاع این اجازه را می دهند و نتیجه همیشه افزایش قابل توجهی در عملکرد برنامه است.

زبان‌های برنامه‌نویسی سطح بالایی از انتزاع با هدف نزدیک‌تر کردن روش نوشتن برنامه‌ها تا حد امکان به اشکال معمول نوشتن برای کاربران رایانه، به ویژه عبارات ریاضی، و همچنین به گونه‌ای که مورد توجه قرار نگیرد، توسعه داده شد. ویژگی های فنی خاص رایانه های فردی در برنامه ها. زبان اسمبلی با در نظر گرفتن ویژگی های پردازنده توسعه یافته است، بنابراین، برای نوشتن صحیح برنامه به زبان اسمبلی، به طور کلی باید معماری پردازنده کامپیوتر مورد استفاده را بدانید. با این حال، با در نظر گرفتن توزیع غالب رایانه‌های شخصی سازگار با رایانه شخصی و بسته‌های نرم‌افزاری آماده برای آنها، لازم نیست به این موضوع فکر کنید، زیرا چنین نگرانی‌هایی توسط شرکت‌های توسعه‌دهنده نرم‌افزارهای تخصصی و جهانی انجام می‌شود.

2. درباره کامپایلرها

کدام اسمبلر بهتر است؟

برای پردازنده x86-x64، بیش از دوجین کامپایلر اسمبلر مختلف موجود است. آنها در مجموعه ویژگی ها و نحو مختلف متفاوت هستند. برخی از کامپایلرها برای مبتدیان و برخی دیگر برای برنامه نویسان پیشرفته مناسب تر هستند. برخی از کامپایلرها کاملاً مستند هستند، برخی دیگر اصلاً مستندی ندارند. برای برخی از کامپایلرها، نمونه های برنامه نویسی زیادی توسعه داده شده است. آموزش‌ها و کتاب‌هایی برای برخی اسمبلرها نوشته شده است که به صورت جزئی وارد سینتکس می‌شوند، برخی دیگر چیزی ندارند. کدام اسمبلر بهتر است؟

با توجه به لهجه‌های متعدد اسمبلرها برای x86-x64 و زمان محدود برای مطالعه آنها، ما به یک مرور مختصر از کامپایلرهای زیر اکتفا می‌کنیم: MASM، TASM، NASM، FASM، GoASM، Gas، RosAsm، HLA.

دوست دارید از چه سیستم عاملی استفاده کنید؟

این اولین سوالی است که باید به آن پاسخ دهید. غنی ترین اسمبلر اگر برای کار با سیستم عاملی که قصد استفاده از آن را دارید طراحی نشده باشد، هیچ سودی برای شما نخواهد داشت.
پنجره ها DOS لینوکس BSD QNX MacOS در حال اجرا است
پردازنده اینتل / AMD
FASM ایکس ایکس ایکس ایکس
گاز ایکس ایکس ایکس ایکس ایکس ایکس
GoAsm ایکس
HLA ایکس ایکس
MASM ایکس ایکس
NASM ایکس ایکس ایکس ایکس ایکس ایکس
روزاسم ایکس
TASM ایکس ایکس

پشتیبانی 16 بیتی

اگر اسمبلر از DOS پشتیبانی می کند، دستورالعمل های 16 بیتی را نیز پشتیبانی می کند. همه اسمبلرها توانایی نوشتن کدی را ارائه می دهند که از عملوندهای 16 بیتی استفاده می کند. پشتیبانی 16 بیتی به این معنی است که می توانید کدی ایجاد کنید که بر روی یک مدل حافظه خرد شده 16 بیتی اجرا شود (در مقایسه با مدل حافظه تخت 32 بیتی که توسط اکثر سیستم عامل های مدرن استفاده می شود).

پشتیبانی 64 بیتی

به استثنای TASM، که Borland در اواسط دهه 2000 علاقه خود را به آن از دست داد، و حتی برنامه های 32 بیتی را به طور کامل پشتیبانی نمی کند، همه گویش های دیگر از توسعه برنامه های کاربردی 64 بیتی پشتیبانی می کنند.

قابل حمل بودن برنامه ها

بدیهی است که قرار نیست کد اسمبلی x86-x64 که روی پردازنده دیگری اجرا می شود بنویسید. با این حال، حتی در یک پردازنده، ممکن است با مشکلات حمل و نقل مواجه شوید. به عنوان مثال، اگر قصد دارید برنامه های زبان اسمبلی خود را تحت سیستم عامل های مختلف کامپایل و استفاده کنید. NASM و FASM را می توان بر روی سیستم عامل هایی که پشتیبانی می کنند استفاده کرد.

آیا قصد دارید برنامه ای را در اسمبلر بنویسید و سپس آن برنامه را از یک سیستم عامل به سیستم عامل دیگر با کد منبع "Recompiled" پورت کنید؟ این ویژگی توسط گویش HLA پشتیبانی می شود. آیا انتظار دارید بتوانید برنامه های ویندوز و لینوکس را با کمترین تلاش در اسمبلر ایجاد کنید؟ اگر چه، اگر با یک سیستم عامل کار می کنید و مطلقاً قصد ندارید در هیچ سیستم عامل دیگری کار کنید، این مشکل شما را نگران نمی کند.

پشتیبانی از ساختارهای زبان سطح بالا

برخی اسمبلرها نحو توسعه یافته ای را ارائه می کنند که ساختارهای کنترل سطح بالا مخصوص زبان (مانند IF، WHILE، FOR و غیره) را ارائه می دهد. چنین ساختارهایی می‌توانند یادگیری اسمبلر را آسان‌تر کنند و به شما در نوشتن کدهای خواناتر کمک کنند. برخی از اسمبلرها دارای "ساختارهای سطح بالا" با قابلیت های محدود هستند. برخی دیگر ساختارهای سطح کلان سطح بالا را ارائه می دهند.

اگر ترجیح می دهید در سطح کدگذاری دستورالعمل ماشین کار کنید، هیچ اسمبلری شما را مجبور به استفاده از ساختارهای کنترل سطح بالا یا انواع داده ها نمی کند. سازه‌های سطح بالا توسعه‌ای از زبان ماشین زیربنایی هستند که در صورت راحتی می‌توانید از آنها استفاده کنید.

کیفیت مستندات

قابلیت استفاده از اسمبلر ارتباط مستقیمی با کیفیت مستندات آن دارد. با توجه به میزان کاری که صرف ایجاد یک گویش اسمبلی می شود، نویسندگان کامپایلر به سختی زحمت ایجاد مستندات برای این گویش را می دهند. نویسندگان، با گسترش زبان خود، فراموش می کنند که این پسوندها را مستند کنند.

جدول زیر کیفیت راهنمای اسمبلر مرجع ارائه شده به همراه محصول را شرح می دهد:

مستندات نظرات (1)
FASM خوب نویسنده بیشتر وقت آزاد خود را به توسعه یک FASMG نوآورانه اختصاص می دهد. با این وجود، نویسنده گهگاه از FASM پشتیبانی می‌کند، کتابچه‌های راهنما را به‌روزرسانی می‌کند، و عملکردهای جدیدی را در انجمن خود شرح می‌دهد. مستندات خیلی خوبه صفحه وب مستندات
گاز
بد
مستند ضعیف است و مستندات نسبتاً "عمومی" است. gas اسمبلری است که به گونه ای طراحی شده است که نوشتن کد برای پردازنده های مختلف را آسان کند. اسنادی که وجود دارد عمدتاً کدهای شبه و دستورالعمل های اسمبلی را توصیف می کند. عملا هیچ سندی در حالت عملیاتی "intel_syntax" وجود ندارد. کتاب هایی که از نحو AT&T استفاده می کنند: برنامه نویسی از ابتدا نوشته جاناتون بارتلت و زبان حرفه ای اسمبلی نوشته ریچارد بلوم، کنستانتین بولدیشف.
GoAsm
ضعیف
بیشتر نحو در کتابچه راهنما پوشش داده شده است و یک کاربر با تجربه آنچه را که به دنبالش است پیدا خواهد کرد. تعداد زیادی آموزش و ارسال شده در سایت (http://www.godevtool.com/). چندین آموزش GoAsm:
  • کتاب راهنمای پاتریک رویز
HLA
آبشستگی
HLA دارای راهنمای مرجع 500 صفحه ای است. این سایت حاوی ده ها مقاله و مستندات HLA است.
MASM
خوب
مایکروسافت اسناد قابل توجهی برای MASM نوشته است، تعداد زیادی کتاب مرجع برای این گویش نوشته شده است.
NASM
خوب
نویسندگان NASM نرم افزارهای بیشتری را برای این گویش می نویسند و نوشتن دستی را برای بعداً باقی می گذارند. NASM برای مدت طولانی وجود داشته است، بنابراین چندین نویسنده برای NASM کتابچه راهنمای جف دانتمان نوشتند "زبان مونتاژ مرحله به مرحله: برنامه نویسی با لینوکس"، جاناتان لتو "نوشتن یک برنامه مفید با NASM"، به زبان روسی کتابی از Stolyarov (وب سایت A.V. Stolyarov).
روزاسم
ضعیف
"آموزش های آنلاین" خیلی جالب نیست.
TASM
خوب
بورلند در یک زمان راهنماهای مرجع عالی تولید کرده است، و راهنمای مرجع برای TASM توسط نویسندگان مشتاقی که به Borland وابسته نیستند نوشته شده است. اما Borland دیگر از TASM پشتیبانی نمی کند، بنابراین بسیاری از اسناد TASM چاپ نشده است و یافتن آن روز به روز دشوارتر می شود.

کتاب های درسی و مواد آموزشی

البته مستندات زبان اسمبلی بسیار مهم است. حتی برای تازه کارها و دیگرانی که زبان اسمبلی را می آموزند (یا ویژگی های پیشرفته یک زبان اسمبلی معین) علاقه بیشتری دارد، در دسترس بودن اسناد خارج از کتابچه راهنمای مرجع برای زبان است. اکثر مردم خواهان آموزش نحوه برنامه نویسی در اسمبلی هستند که چیزی فراتر از ارائه نحو دستورات ماشین باشد و انتظار دارند به خواننده گفته شود که چگونه این دستورالعمل ها را برای حل مشکلات دنیای واقعی ترکیب کند.

MASM پیشرو در میان حجم عظیمی از کتاب‌هایی است که نحوه برنامه‌نویسی به این گویش را توضیح می‌دهند. ده ها کتاب وجود دارد که از MASM به عنوان اسمبل کننده برای آموزش اسمبلر استفاده می کنند.

اکثر کتاب های درسی اسمبلر MASM/TASM به آموزش برنامه نویسی MS-DOS ادامه می دهند. اگرچه، به تدریج آموزش هایی ظاهر می شوند که برنامه نویسی را در ویندوز و لینوکس آموزش می دهند.

نظرات (1)
FASM چندین آموزش که برنامه نویسی FASM را توضیح می دهند:
  • S.A. Norseev "توسعه برنامه های پنجره در FASM"
  • Ruslan Ablyazov "برنامه نویسی به زبان اسمبلی در پلت فرم x86-64"
گاز
آموزش استفاده از نحو AT&T
آموزش اسمبلر لینوکس برای برنامه نویسان C
HLA
نسخه 32 بیتی "هنر برنامه نویسی زبان اسمبلی" (به دو صورت الکترونیکی و چاپی وجود دارد)، برنامه نویسی برای ویندوز یا لینوکس
MASM
تعداد زیادی کتاب در مورد آموزش برنامه نویسی DOS. کتاب های زیادی در مورد برنامه نویسی Win32 / 64 Pirogov، Yurov، Zubkov، Flinov وجود ندارد.
NASM
بسیاری از کتاب ها به برنامه نویسی در DOS، Linux، Windows اختصاص داده شده است. کتاب زبان اسمبلی جف دانتمن گام به گام: برنامه نویسی با لینوکس از NASM برای لینوکس و داس استفاده می کند. در آموزش پل کارتر از NASM (DOS، Linux) استفاده شده است.
TASM
مانند MASM، تعداد زیادی کتاب مبتنی بر DOS برای TASM نوشته شده است. اما از آنجایی که بورلند دیگر از این محصول پشتیبانی نمی کند، آنها نوشتن کتاب در مورد استفاده از TASM را متوقف کردند. تام سوان یک آموزش در مورد TASM با چندین فصل در مورد برنامه نویسی ویندوز نوشت.

3. ادبیات و منابع وب

مبتدیان

  1. زبان Abel P. Assembler برای IBM PC و برنامه نویسی. - م .: دبیرستان، 1992 .-- 447 ص.
  2. Bradley D. برنامه نویسی به زبان اسمبلی برای رایانه های شخصی از IBM. - M.: Radio and Communication, 1988. - 448 p.
  3. Galiseev G.V. اسمبلر IBM PC. کتاب خودآموزی .: - M .: انتشارات "ویلیامز"، 2004. - 304 ص .: ill.
  4. Dao L. برنامه نویسی ریزپردازنده 8088 .-- M .: Mir, 1988 .-- 357 p.
  5. ژوکوف A.V.، Avdyukhin A.A. مونتاژ کننده. - SPb .: BHV-Petersburg, 2003 .-- 448 p.: ill.
  6. Zubkov S.V.، اسمبلر برای DOS، Windows و UNIX. - M .: DMK Press, 2000 .-- 608 p .: ill. (سری "برای برنامه نویسان").
  7. زبان اسمبلی Irwin K. برای پردازنده های اینتل، ویرایش چهارم .: trans. از انگلیسی - M .: انتشارات "ویلیامز"، 2005. - 912 ص .: ill. - موازی. دختر انگلیسی (به آخرین نسخه هفتم در نسخه اصلی نیز مراجعه کنید)
  8. Norton P., Souhe D. Language Assembly for IBM PC. - M.: Computer, 1992. - 352 p.
  9. پیلشچیکوف V.N. برنامه نویسی به زبان اسمبلی IBM PC - M .: DIALOG-MEPhI, 1994–2014 288 p.
  10. اسکلیاروف I.S. آموزش اسمبلر در 7 روز www.sklyaroff.ru

پیشرفته

  1. Kaspersky K. اصول هک. هنر جدا کردن قطعات. - M .: SOLON-Press, 2004.448 p. - (سریال "Kodokopatel")
  2. Kaspersky K. تکنیک برای اشکال زدایی برنامه ها بدون کد منبع. - SPb .: BHV-Petersburg, 2005 .-- 832 p.: ill.
  3. ویروس های کامپیوتری Kaspersky K. داخل و خارج. - SPb .: Peter, 2006 .-- 527 p .: ill.
  4. Kaspersky K. یادداشت های یک محقق ویروس کامپیوتری. - SPb .: Peter, 2006 .-- 316 p .: ill.
  5. Knut D. The Art of Programming, جلد 3. مرتب سازی و جستجو, ویرایش دوم: ترجمه. از انگلیسی - M .: انتشارات "ویلیامز"، 2003. - 832 ص .: ill. - موازی. دختر انگلیسی
  6. کولیسنیچنکو D.N. روت کیت برای ویندوز تئوری و عمل برنامه نویسی "کلاه های نامرئی"، اجازه می دهد تا داده ها، فرآیندها، اتصالات شبکه را از سیستم پنهان کنید. - SPb .: Nauka i Tekhnika, 2006 .-- 320 p .: ill.
  7. لیامین L.V. مونتاژگر ماکرو MASM.– M.: رادیو و ارتباطات، 1994.– 320 ص .: ill.
  8. Magda Y. اسمبلر برای پردازنده های پنتیوم اینتل. - SPb .: Peter, 2006 .-- 410 p .: ill.
  9. Mayko G.V. اسمبلر برای IBM PC - M .: Business-Inform, Sirin, 1997. - 212 p.
  10. وارن جی. ترفندهای الگوریتمی برای برنامه نویسان، ویرایش دوم: ترجمه. از انگلیسی - M .: انتشارات "ویلیامز"، 2004. - 512 ص .: ill. - موازی. دختر انگلیسی
  11. اسکلیاروف I.S. هنر محافظت و هک کردن اطلاعات - SPb .: BHV-Petersburg, 2004 .-- 288 p.: ill.
  12. Weatherrell C. Studies for programmers: Per. از انگلیسی - م .: میر، 1361 .-- 288 ص.
  13. کتابخانه الکترونیکی برادران فرولوف www.frolov-lib.ru
  14. A.A. چکاتوف استفاده از توربو اسمبلر در توسعه نرم افزار - کیف: دیالکتیک، 1995. - 288 ص.
  15. Yurov V. Assembler: کتاب مرجع ویژه.- SPb .: Peter, 2001.- 496 p.: ill.
  16. Yurov V. اسمبلر. کارگاه. ویرایش دوم - SPb .: Peter, 2006 .-- 399 p .: ill.
  17. Yurov V. اسمبلر. کتاب درسی برای دانشگاه ها. ویرایش دوم - SPb .: Peter, 2007 .-- 637 p .: ill.
  18. دوره آموزشی Pirogov V. Assembler. 2001 دانش
  19. دوره آموزشی Pirogov V. ASSEMBLER 2003 Knowledge-BHV
  20. V. Pirogov اسمبلر برای ویندوز
    چاپ اول - M .: انتشارات Mlgachev S.V.، 2002
    ویرایش دوم - SPb.:. BHV-Petersburg, 2003 - 684 p.: ill.
    ویرایش سوم - SPb.:. BHV-Petersburg، 2005 - 864 p.: ill.
    ویرایش چهارم - SPb.:. BHV-Petersburg، 2012 - 896 p.: ill.
  21. V. Pirogov Assembler با مثال. - SPb.:. BHV-Petersburg، 2012 - 416 p.: ill.
  22. V. Pirogov مونتاژ و جداسازی قطعات. - SPb.:. BHV-Petersburg, 2006.-- 464 p.: ill.
  23. Pirogov V. روی کتاب "برنامه نویسی 64 بیتی در زبان اسمبلی (ویندوز، یونیکس)" کار کرد. این کتاب برنامه نویسی با fasm را در ویندوز 64 بیتی و یونیکس پوشش می دهد
  24. Yurov V., Khoroshenko S. Assembler: دوره آموزشی.- SPb .: Peter, 1999. - 672 p.
  25. ریزپردازنده‌های Yu-Zheng Liu, Gibson G. 8086/8088. معماری، برنامه نویسی و طراحی سیستم های میکرو کامپیوتری - M .: Radio and Communication, 1987. - 512 p.
  26. Agner Fog: منابع بهینه سازی نرم افزار (مونتاژ / c ++) 1996 - 2017.

پولیاکوف آندری والریویچ

http://info-master.su

[ایمیل محافظت شده]

av-inf.blogspot.ru

در تماس با:

vk.com/id185471101

facebook.com/100008480927503

یک صفحه از یک کتاب:

http://av-assembler.ru/asm/afd/assembler-for-dummy.htm

توجه!

تمامی حقوق این کتاب متعلق به آندری وی پلیاکوف است. هیچ بخشی از این کتاب بدون رضایت نویسنده قابل تکثیر نیست.

اطلاعات مندرج در این کتاب از منابعی که نویسنده آن را معتبر دانسته است به دست آمده است. اما با توجه به خطاهای احتمالی انسانی یا فنی، نویسنده نمی تواند صحت و کامل بودن اطلاعات ارائه شده را تضمین کند و مسئولیتی در قبال خطاها و خسارات احتمالی ناشی از استفاده از این سند ندارد.

1. مجوزها

استفاده از کتاب برای مقاصد اطلاعاتی و آموزشی (فقط برای استفاده شخصی) مجاز است. توزیع رایگان کتاب مجاز است.

2. محدودیت ها

استفاده از کتاب برای مقاصد تجاری (فروش، قرار دادن در منابع با دسترسی پولی و غیره) ممنوع است. تغییر در متن کتاب ممنوع است. انتساب ممنوع است

را نیز ببینید توافقنامه مجوز.

پولیاکوف A.V.

اسمبل کننده برای Dummies

پولیاکوف A.V. اسمبل کننده برای آدمک ها.

پیشگفتار ................................................ ................................................ ................................................ ...........

معرفی ................................................. ................................................ ................................................ ...................

ن چیزهای زیادی در مورد پردازنده ها.......................................................................................................................................................

1. شروع سریع ...................................... ................................................ ................................................ ......

1.1. برنامه اول ...................................... ................................................ ................................................ .....

1.1.1. Emu8086 ...................................... ................................................ ................................................ ...........

1.1.2. اشکال زدایی ................................................ ................................................ ................................................ .............

1.1.3. MASM، TASM و WASM ............................................ ................................................ ......................................

1.1.3.1. مونتاژ در TASM ...................................... ................................................ ................................................

1.1.3.2. مونتاژ در MASM ...................................... ................................................ ......................................

1.1.3.3. مونتاژ در WASM ...................................... ................................................ ......................................

1.1.3.4. اجرای برنامه ................................................ ................................................ ......................................

1.1.3.5. استفاده از فایل های BAT ...................................... ................................................ . ......................................

1.1.4. ویرایشگر هگزادسیمال ...................................... ................................................ ...................

خلاصه................................................. ................................................ ................................................ ......................

2. مقدمه ای بر اسمبلر ...................................... ................................................ ......................................

2.1. به AK یک کامپیوتر دارد...............................................................................................................................................

2.1.1. ساختار پردازنده ...................................................... ................................................ ................................

2.1.2. رجیسترهای پردازنده ...................................... ................................................ ......................................

2.1.3. چرخه اجرای فرمان ...................................................... ................................................ ............................

2.1.4. سازماندهی حافظه ................................................ ................................................ ......................................

2.1.5. حالت واقعی ................................................ ................................................ ......................................

2.1.6. حالت محافظت شده ................................................ ................................................ ......................................

2.2. با سیستم های محاسباتی.....................................................................................................................................................

2.2.1. سیستم اعداد دودویی ...................................... ................................................ ......................

2.2.2. سیستم اعداد هگزادسیمال ................................................ ................................................ ....

2.2.3. سایر سیستم ها ................................................ ................................................ ................................................

2.3. پ ویرایش داده ها در حافظه کامپیوتر.............................................................................................................

2.3.1. اعداد مثبت ...................................... ................................................ ................................

2.3.2. اعداد منفی ..................................................... ................................................ ................................

2.3.3. سرریز چیست ...................................... ................................................ ................................

2.3.4. ثبت پرچم ها ...................................... ................................................ ................................................

2.3.5. کدهای کاراکتر ...................................... ................................................ ................................................

2.3.6. اعداد واقعی ................................................ ................................................ ......................................

2.3.6.1. اولین تلاش................................................ ................................................ ................................................ ..........

2.3.6.2. ضبط اعداد عادی ..................................................... ................................................ ................................

2.3.6.3. تبدیل جزء کسری به باینری ...................................... ................................................ . ...

2.3.6.4. نمایش اعداد حقیقی در حافظه کامپیوتر ...................................... .................................................

2.3.6.5. اعداد نقطه ثابت ..................................................... ................................................ . ................................

2.3.6.6. اعداد ممیز شناور ...................................... ................................................ . ......................................

توافقنامه مجوز................................................ ................................................ ................................

پیش گفتار

اسمبلر یک کلمه جادویی است که برنامه نویسان تازه کار را بیدار می کند. هنگام برقراری ارتباط با یکدیگر، آنها لزوماً می گویند که در جایی شخصی یک "آدم" آشنا دارد که می تواند کدهای منبع را به زبان اسمبلی به عنوان متن کتاب بخواند. در همان زمان، به عنوان یک قاعده، زبان اسمبلی به عنوان چیزی غیرقابل دسترس برای فانیان صرف تلقی می شود.

این تا حدی درست است. شما می توانید چند دستور ساده را یاد بگیرید و حتی نوعی برنامه بنویسید، اما تنها در صورتی می توانید به یک استاد واقعی (در هر کسب و کاری) تبدیل شوید که یک فرد مبانی نظری را به خوبی بداند و بفهمد که چه کاری و چرا انجام می دهد.

از سوی دیگر، برنامه نویسان باتجربه سطح بالا متقاعد شده اند که زبان اسمبلی یادگاری از گذشته است. بله، ابزارهای توسعه در 20 سال گذشته پیشرفت های زیادی داشته اند. اکنون می توانید یک برنامه ساده بدون دانستن هیچ زبان برنامه نویسی بنویسید. با این حال، مواردی مانند میکروکنترلرها را فراموش نکنید. و در برنامه نویسی کامپیوتر، برخی از کارها با استفاده از زبان اسمبلی آسانتر و سریعتر حل می شوند.

این کتاب برای کسانی در نظر گرفته شده است که از قبل مهارت های برنامه نویسی سطح بالایی دارند، اما می خواهند "به سخت افزار" نزدیکتر شوند و بفهمند که چگونه دستورالعمل های پردازنده اجرا می شوند، چگونه حافظه تخصیص داده می شود، چگونه دستگاه های سخت افزاری مختلف مانند درایوهای دیسک مدیریت می شوند و غیره. .. پ.

کتاب به چند بخش تقسیم شده است. بخش اول یک شروع سریع است. اصول اولیه برنامه نویسی در زبان اسمبلی، خود اسمبلرها (کامپایلرها) و روش های کار با اسمبلرها را به طور خلاصه توضیح می دهد. اگر در برنامه نویسی در سطح بالا اعتماد به نفس دارید، اما می خواهید بر اصول برنامه نویسی سطح پایین تسلط داشته باشید، شاید فقط نیاز به خواندن این بخش داشته باشید.

بخش دوم مواردی مانند سیستم های اعداد، نمایش داده ها در حافظه کامپیوتر و غیره را شرح می دهد، یعنی چیزهایی که مستقیماً به برنامه نویسی مربوط نیستند، اما بدون آنها برنامه نویسی حرفه ای غیرممکن است. همچنین، در بخش دوم با جزئیات بیشتری به اصول کلی برنامه نویسی زبان اسمبلی پرداخته می شود.

بقیه بخش ها چند نمونه خاص از برنامه نویسی زبان اسمبلی را توضیح می دهند، حاوی مواد مرجع و غیره هستند.

اصول برنامه نویسی اصلا در این کتاب توضیح داده نشده است، بنابراین برای مبتدیان اکیداً توصیه می کنم که با کتاب آشنا شوند. چگونه یک برنامه نویس شویم، که در آن اصول کلی برنامه نویسی "روی انگشتان" توضیح داده شده است و نمونه هایی از ایجاد برنامه های ساده از برنامه برای رایانه تا برنامه برای ماشین های CNC به طور مفصل در نظر گرفته شده است.

معرفی

بیایید با اصطلاحات شروع کنیم.

کد ماشین سیستمی از دستورالعمل های یک کامپیوتر خاص (پردازنده) است که مستقیماً توسط پردازنده تفسیر می شود. یک دستورالعمل معمولا یک عدد صحیح است که در یک ثبات پردازنده نوشته می شود. پردازنده این عدد را می خواند و عملیاتی را انجام می دهد که با این دستورالعمل مطابقت دارد. این به طور عامیانه در کتاب توضیح داده شده است چگونه یک برنامه نویس شویم.

زبان برنامه نویسی سطح پایین(زبان برنامه نویسی سطح پایین) زبان برنامه نویسی است که تا حد امکان به برنامه نویسی در کدهای ماشین نزدیک است. برخلاف کدهای ماشینی، در یک زبان سطح پایین، هر دستور نه به یک عدد، بلکه به یک نام فرمان کوتاه شده (مانمونیک) مربوط می شود. برای مثال، ADD مخفف ADDITION است. بنابراین، استفاده از یک زبان سطح پایین، نوشتن و خواندن برنامه ها را بسیار ساده می کند (در مقایسه با برنامه نویسی در کدهای ماشین). یک زبان سطح پایین مختص پردازنده است. به عنوان مثال، اگر یک برنامه سطح پایین برای پردازنده PIC نوشته اید، می توانید مطمئن باشید که با پردازنده AVR کار نمی کند.

زبان برنامه نویسی سطح بالایک زبان برنامه نویسی است که تا حد امکان به زبان انسانی نزدیک است (معمولاً به انگلیسی، اما زبان های برنامه نویسی در زبان های ملی وجود دارد، به عنوان مثال، زبان 1C بر اساس روسی است). یک زبان سطح بالا عملاً به یک پردازنده یا یک سیستم عامل خاص گره نمی خورد (مگر اینکه دستورالعمل های خاصی استفاده شود).

زبان اسمبلی یک زبان برنامه نویسی سطح پایین است که شما برنامه های خود را با آن می نویسید. هر پردازنده زبان اسمبلی مخصوص به خود را دارد.

اسمبلر برنامه خاصی است که کد منبع برنامه شما را که به زبان اسمبلی نوشته شده است به یک فایل اجرایی (فایل با پسوند EXE یا COM) تبدیل می کند (اسمبل می کند، یعنی اسمبل می کند). به طور دقیق، برنامه های اضافی برای ایجاد یک فایل اجرایی، نه فقط یک اسمبلر، مورد نیاز است. اما بعداً در مورد آن بیشتر ...

در بیشتر موارد می گویند اسمبلر، اما به معنای زبان اسمبلی است. اکنون می دانید که اینها چیزهای متفاوتی هستند و گفتن آن کاملاً صحیح نیست. اگرچه همه برنامه نویسان شما را درک خواهند کرد.

بر خلاف زبان‌های سطح بالا مانند پاسکال، بیسیک و غیره، هر اسمبلر زبان اسمبلی مخصوص به خود را دارد. این قانون اساساً زبان اسمبلی را از زبان های سطح بالا متمایز می کند. کدهای منبع یک برنامه (یا به سادگی "منبع") نوشته شده در یک زبان سطح بالا، در اکثر موارد می توانید با کامپایلرهای مختلف برای پردازنده های مختلف و سیستم عامل های مختلف کامپایل کنید. انجام این کار با منابع اسمبلر بسیار دشوارتر خواهد بود. البته این تفاوت برای اسمبلرهای مختلفی که برای پردازنده های یکسان طراحی شده اند تقریبا نامحسوس است. اما واقعیت امر این است که برای هر پردازنده، مونتاژ کننده و زبان اسمبلر مخصوص به خود وجود دارد. از این نظر، برنامه نویسی در زبان های سطح بالا بسیار آسان تر است. با این حال، شما باید برای تمام لذت ها هزینه کنید. در مورد زبان های سطح بالا، ممکن است با مواردی مانند حجم فایل اجرایی بزرگتر، عملکرد بدتر و غیره مواجه شویم.

در این کتاب فقط در مورد برنامه نویسی برای کامپیوترهایی با پردازنده های اینتل (یا سازگار) صحبت خواهیم کرد. به منظور بررسی در عمل داده شده

v در کتاب مثال ها به برنامه های زیر (یا حداقل برخی از آنها) نیاز دارید:

1. Emu8086. برنامه خوب، به خصوص برای مبتدیان. شامل یک ویرایشگر منبع و برخی موارد مفید دیگر است. روی ویندوز کار می کند، اگرچه برنامه ها تحت DOS نوشته می شوند. متأسفانه، برنامه هزینه دارد (اما ارزشش را دارد))). برای جزئیات بیشتر به http://www.emu8086.com مراجعه کنید.

2. TASM - توربو اسمبلر از Borland. شما می توانید برنامه هایی را هم برای DOS و هم برای ویندوز ایجاد کنید. همچنین هزینه دارد و در حال حاضر دیگر پشتیبانی نمی شود (و Borland دیگر وجود ندارد). در کل چیز خوبی است.

3. MASM - اسمبلر از مایکروسافت (مخفف MACRO assembler، نه Microsoft Assembler، همانطور که بسیاری از افراد ناآشنا فکر می کنند). شاید محبوب ترین اسمبلر برای پردازنده های اینتل باشد. هنوز هم پشتیبانی می شود. برنامه Shareware. یعنی اگه جدا بخری اونوقت هزینه داره. اما به صورت رایگان برای مشترکین MSDN در دسترس است و در مجموعه ویژوال استودیو مایکروسافت گنجانده شده است.

4. WASM - اسمبلر از Watcom. مانند همه موارد دیگر، مزایا و معایبی دارد.

5. اشکال زدایی - دارای ویژگی های متوسط ​​است، اما دارای یک مزیت بزرگ است - در مجموعه استاندارد ویندوز گنجانده شده است. آن را در پوشه WINDOWS \ COMMAND یا WINDOWS \ SYSTEM32 جستجو کنید. اگر آن را پیدا نکردید، در پوشه های دیگر دایرکتوری WINDOWS.

6. داشتن نیز مطلوب استهر ویرایشگر هگز... به مدیر فایل DOS آسیب ندهید، برای مثال Volkov Commander (VC) یا Norton Commander (NC). همچنین می توان از آنها برای مشاهده کدهای هگزادسیمال فایل استفاده کرد، اما قابل ویرایش نیستند. تعداد زیادی ویرایشگر هگزادسیمال رایگان در اینترنت وجود دارد. در اینجا یکی است: McAfee FileInsight نسخه 2.1. از همان ویرایشگر می توان برای کار با کدهای منبع برنامه ها استفاده کرد. با این حال، من دوست دارم این کار را با ویرایشگر زیر بهتر انجام دهم:

7. ویرایشگر متن... برای نوشتن کد منبع برنامه های شما ضروری است. من می توانم ویرایشگر رایگان PSPad را توصیه کنم که از بسیاری از زبان های برنامه نویسی از جمله Assembly پشتیبانی می کند.

تمام برنامه ها (و برنامه های نمونه) ارائه شده در این کتاب از نظر عملکرد آزمایش شده اند. و این برنامه ها هستند که برای اجرای نمونه برنامه های این کتاب استفاده می شوند.

و با این حال - کد منبع نوشته شده، به عنوان مثال، برای Emu8086، کمی با کد نوشته شده، به عنوان مثال، برای TASM متفاوت است. این تفاوت ها مورد بحث قرار خواهد گرفت.

اکثر برنامه های کتاب برای MASM نوشته شده است. اول، زیرا این اسمبلر محبوب ترین است و هنوز هم پشتیبانی می شود. دوم، زیرا با MSDN و مجموعه ویژوال استودیو مایکروسافت عرضه می شود. و ثالثاً به این دلیل که من صاحب یک نسخه مجاز از MASM هستم.

اگر قبلاً اسمبلری دارید که در لیست بالا قرار ندارد، باید خودتان دستور آن را پیدا کنید و راهنمای کاربر را بخوانید تا نحوه صحیح کار با آن را بیاموزید. اما توصیه های کلی ارائه شده در این کتاب برای هر مونتاژکننده (خوب، یا تقریباً هر) معتبر خواهد بود.

کمی در مورد پردازنده ها

پردازنده مغز کامپیوتر است. از نظر فیزیکی، این یک ریزمدار ویژه با چند صد پین است که در مادربرد قرار می گیرد. اگر به سختی می توانید تصور کنید که چیست، توصیه می کنم مقاله را بخوانید ساختگی در مورد کامپیوتر.

حتی در دنیای کامپیوترها نیز تعداد کمی پردازنده وجود دارد. اما در کنار کامپیوتر، تلویزیون، ماشین لباسشویی، تهویه مطبوع، سیستم های کنترل موتورهای احتراق داخلی و غیره نیز وجود دارد که پردازنده ها (ریزپردازنده ها، میکروکنترلرها) نیز بسیار مورد استفاده قرار می گیرند.

هر پردازنده مجموعه ای از ثبات های خاص خود را دارد. رجیسترهای پردازنده مکان های حافظه خاصی هستند که مستقیماً روی تراشه پردازنده قرار دارند. از رجیسترها برای اهداف مختلفی استفاده می شود (جزئیات بیشتر در مورد رجیسترها در زیر نوشته خواهد شد).

هر پردازنده مجموعه ای از دستورالعمل های خاص خود را دارد. دستور پردازنده در یک ثبات خاص نوشته می شود و سپس پردازنده این دستورالعمل را اجرا می کند. ما در مورد دستورالعمل‌ها و ثبت‌های پردازنده زیاد و اغلب در سراسر کتاب صحبت خواهیم کرد. برای مبتدیان این کتاب را توصیه می کنم چگونه یک برنامه نویس شویم، جایی که در کلی ترین اصطلاح، اما به زبانی قابل فهم، در مورد اصول اجرای یک برنامه توسط کامپیوتر گفته می شود.

دستور از نظر پردازنده چیست؟ این فقط یک عدد است. با این حال، پردازنده های مدرن می توانند چندین صد دستورالعمل داشته باشند. به خاطر سپردن همه آنها دشوار خواهد بود. پس چگونه برنامه می نویسید؟ برای ساده کردن کار برنامه نویس، زبان اسمبلی اختراع شد که در آن هر دستور مربوط به یک کد یادگاری است. به عنوان مثال، عدد 4 مربوط به یادگاری ADD است. گاهی اوقات به زبان اسمبلی، زبان دستورالعمل یادگاری نیز گفته می شود.

1. شروع سریع

1.1. برنامه اول

به طور معمول، اولین مثال برنامه ای است که رشته "Hello World!" را چاپ می کند. با این حال، برای شخصی که به تازگی شروع به یادگیری اسمبلر کرده است، چنین برنامه ای بسیار پیچیده خواهد بود (می خندید، اما واقعاً اینطور است - به خصوص در صورت عدم وجود اطلاعات قابل فهم). بنابراین، اولین برنامه ما حتی ساده تر خواهد بود - ما فقط یک کاراکتر - حرف انگلیسی "A" را نمایش می دهیم. و به طور کلی - اگر قبلاً تصمیم گرفته اید برنامه نویس شوید - فوراً طرح صفحه کلید انگلیسی پیش فرض را تنظیم کنید. علاوه بر این، برخی از اسمبلرها و کامپایلرها حروف روسی را قبول نمی کنند. بنابراین، اولین برنامه ما حرف انگلیسی "A" را نمایش می دهد. در ادامه به ایجاد چنین برنامه ای با استفاده از اسمبلرهای مختلف خواهیم پرداخت.

اگر شبیه ساز پردازنده 8086 را دانلود و نصب کرده اید (به بخش مقدمه مراجعه کنید)، می توانید از آن برای ایجاد اولین برنامه های زبان اسمبلی خود استفاده کنید. در حال حاضر (نوامبر 2011) نسخه 4.08 موجود است. در اینجا می توانید به زبان روسی کمک بیابید: http://www.avprog.narod.ru/progs/emu8086/help.html.

برنامه Emu8086 پولی است. با این حال، به مدت 30 روز، می توانید از آن برای آزمایش رایگان استفاده کنید.

بنابراین، شما برنامه Emu8086 را دانلود و بر روی رایانه خود نصب کرده اید. آن را اجرا کرده و از طریق منوی FILE - NEW - COM TEMPLATE (فایل - جدید - قالب فایل COM) یک فایل جدید ایجاد کنید. در ویرایشگر منبع، پس از آن، موارد زیر را مشاهده خواهیم کرد:

برنج. 1.1. ایجاد یک فایل جدید در Emu8086.

در اینجا لازم به ذکر است که برنامه های ایجاد شده با استفاده از Assemblers برای رایانه های دارای ویندوز بر دو نوع COM و EXE هستند. ما بعداً به تفاوت بین این فایل ها خواهیم پرداخت، اما در حال حاضر فقط باید بدانید که برای اولین بار فایل های اجرایی با پسوند COM ایجاد خواهیم کرد، زیرا آنها ساده تر هستند.

پس از ایجاد فایل در Emu8086 همانطور که در بالا توضیح داده شد، در ویرایشگر منبع، خط "add your code listen" - "add your code here" را خواهید دید (شکل 1.1). این خط را حذف می کنیم و به جای آن متن زیر را وارد می کنیم:

بنابراین، متن کامل برنامه به صورت زیر خواهد بود:

علاوه بر این، نظرات در قسمت بالایی وجود دارد (در شکل 1.1 - این متن سبز است). نظر در زبان اسمبلی با یک کاراکتر شروع می شود. (نقطه ویرگول) و تا انتهای خط ادامه می یابد. اگر نمی دانید نظرات چیست و چرا به آنها نیاز است، به کتاب مراجعه کنید چگونه یک برنامه نویس شویم... همانطور که قبلاً گفتم، در اینجا اصول برنامه نویسی را توضیح نمی دهیم، زیرا کتابی که اکنون می خوانید برای افرادی طراحی شده است که با اصول برنامه نویسی آشنا هستند.

همچنین توجه داشته باشید که زبان اسمبلی به حروف کوچک و بزرگ حساس نیست. می توانید RET، ret یا Ret بنویسید - آنها همان فرمان خواهند بود.

می توانید این فایل را در جایی روی دیسک ذخیره کنید. اما شما مجبور نیستید. برای اجرای برنامه، دکمه EMULATE (با یک مثلث سبز رنگ) یا کلید F5 را فشار دهید. دو پنجره باز می شود: پنجره شبیه ساز و پنجره کد منبع (شکل 1.2).

V پنجره شبیه ساز رجیسترها و دکمه های کنترل برنامه را نمایش می دهد. پنجره منبع منبع برنامه شما را نشان می دهد و خطی را که در حال حاضر اجرا می شود برجسته می کند. همه اینها برای مطالعه و اشکال زدایی برنامه ها بسیار راحت است. اما ما هنوز به آن نیاز نداریم.

V در پنجره شبیه ساز، می توانید برنامه خود را برای اجرا به طور کامل (دکمه RUN) یا در حالت گام به گام (دکمه SINGLE STEP) اجرا کنید. حالت گام به گام برای رفع اشکال راحت است. خب حالا با دکمه RUN برنامه را برای اجرا شروع می کنیم. پس از آن (اگر هیچ اشتباهی در متن برنامه مرتکب نشده باشید)، پیامی مبنی بر اتمام برنامه خواهید دید (شکل 1.3). در اینجا به شما اطلاع داده می شود که برنامه کنترل را به سیستم عامل منتقل کرده است، یعنی برنامه با موفقیت انجام شده است. در این پنجره روی OK کلیک کنید و در نهایت نتیجه اولین برنامه زبان اسمبلی خود را خواهید دید (شکل 1).

برنج. 1.2. پنجره شبیه ساز Emu8086.

برنج. 1.3. پیام تکمیل برنامه

برنج. 1.4. اولین برنامه شما کامل شد.

مقالات مرتبط برتر