Web Programming C++ SQL Server پایگاه داده ساختمان داده   صفحه اصلی
  زبان اسمبلي > برنامه نويسي اسمبلي  
 
 

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


در اين صفحه ساختار کلی يک برنامه به زبان اسمبلی توضيح داده می شود. به نحوه تعريف متغيرها و ثابت ها، استفاده از راهنماهای اسمبلر و اسمبل کردن و اجرای برنامه نيز اشاره شده است.

اولین برنامه اسمبلی
ساختار یک برنامه اسمبلی
راهنماهای اسمبلر
راهنماهای سگمنت
مدهای آدرس دهی
عملگرهای اندازه


برنامه اسمبلر فايل اسمبلی مبدا با پسوند asm. را به دستورالعمل ماشين تبديل می کند و فايل مقصد با پسوند obj. ايجاد می سازد. اسمبلر MASM متعلق به میکروسافت از محبوب ترین اسمبلرها می باشد بسته MASM32v8 آنرا می توانید از آدرس http://www.masm32.com دانلود و نصب کنید. اسمبلر دیگر TASM از شرکت بورلند است که البته رایگان نیست.

اسمبلر اغلب همراه با یک لینکر است. لینکر link.exe از يک يا ترکيب چند فايل .obj يک برنامه قابل اجرا از نوع exe. يا com. می سازد.

ویراستار جائی است که کدهای برنامه را می نویسید. تعداد بسیار زیادی ویراستار وجود دارد و این به سلیقه شخصی خودتون بستگی دارد که کدام را انتخاب کنید. می توانید از برنامه Notepad ویندوز استفاده کنید که ساده و سریع است یا از Visual Studio که ابزارهای زیادی برای خواناتر کردن کد برنامه دارد.

هر برنامه اسمبلی x86 ساختار ساده زیر را دارد:

; Program Description:
.386
.model flat, stdcall
   ; (Include files here)
.stack
.data
   ; (Initialized Data Declaration)
.data?
   ; (Uninitialized Data Declaration)
.const
    ; (Constant Definitions)
.code
main proc
.
.
    ; (insert executable instructions here)
.
.
Invoke ExitProcess, 0     ; exit to operating system
main endp
; (insert additional procedures here)
end main

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

اولین برنامه اسمبلی که می نویسید که نمایش پیغام "Hello World!" است. توضیح خط به خط برنامه در ادامه داده می شود.

برنامه1. برنامه اسمبلی نمایش پیغام "Hello World!" در پنجره ویندوز.

.386
.model flat, stdcall
option casemap :none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\user32.inc
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\user32.lib
.data
message db "Hello World!", 0
.code
start:
invoke MessageBox, NULL, addr message, addr message, MB_OK
invoke ExitProcess, 0
end start

برنامه2. برنامه اسمبلی نمایش پیغام "Hello World!" در خط فرمان(نسخه کنسول ویندوز).

.386
.model flat, stdcall
option casemap :none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\masm32.lib
.data
message db "Hello World!", 0
.code
start:
invoke StdOut, addr message
invoke ExitProcess, 0
end start

برنامه3. برنامه اسمبلی نمایش پیغام "Hello World!" در خط فرمان با استفاده از وقفه های DOS.

.model small
.stack
.data
message db "Hello world", "$"
.code
start:
mov AX,seg message
mov DS,AX
mov AH,09
lea DX,message
int 21h
mov AX,4c00h
int 21h
end start

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

برنامه اسمبلی را در يک اديتور متن نوشته و با پسوند asm. ذخيره کنيد. فراموش نکنيد که حتما از يک اديتور اسکی استفاده کنيد. سپس با انتخاب command prompt در Start Menu به محیط خط فرمان ویندوز رفته و برنامه اسمبلر ml.exe را برای تولید فایل مقصد obj. اجرا کنید. اگر خطائی در برنامه وجود داشته باشد اسمبلر خطا را گزارش می دهد. درصورتیکه برنامه بدون خطا به فایل مقصد تبدیل شد برنامه لینکر را برای ساختن فایل اجرایی exe. اجرا کنید.

مثال. برنامه hello.asm را در مسیر c:\ ذخیره کنید. دستورات زیر را در خط فرمان وارد کنید.

C:\>masm32\bin\ml /c /Zd /coff hello.asm
C:\>masm32\bin\Link /SUBSYSTEM:CONSOLE hello.obj
C:\>hello

نتیجه اجرای برنامه1

Execution First Assembly Program

نتیجه اجرای برنامه1

Execution First Assembly Program(version2)

برنامه ویژوال استودیو شامل ماکرو اسمبلر نیز هست و فایل ml.exe را در فولدر \VC\bin جایی که ویژوال استودیو نصب شده است می توانید پیدا کنید. اگر این برنامه را روی کامپیوتر خودتان نصب کرده اید می توانید از آن برای نوشتن و اجرای برنامه های اسمبلی هم استفاده کنید. برای مشاهده توضیحات بیشتر درباره ایجاد پروژه اسمبلی در ویژوال استودیو را اینجا کلیک کنید.

ساختار يک برنامه اسمبلی

هربرنامه اسمبلی از تعدادی خط تشکيل شده است (line oriented). هر خط می تواند یک دستورالعمل یا توضیح باشد. دستورالعمل ها به دو دسته تقسيم می شوند: راهنماهای اسمبلر و دستورالعمل های زبان اسمبلی.

راهنماهای اسمبلر(directives) دستورات خاصی هستند که از دستورالعمل های پردازنده نيستند و در فايل ترجمه شده ظاهر نمی شوند بلکه هنگام ترجمه برنامه به اسمبلر مطالبی را می فهمانند (مانند .model, .stack, .data,.code, dw و end).

منظور از دستورالعمل های زبان اسمبلی مجموعه دستورالعمل های 80x86 است که در بخش دستورات اسمبلی توضیح داده شده اند. در زمان ترجمه برنامه اسمبلر معادل کد زبان ماشين آنها را پيدا کرده و جايگزين می کند. دستورات اسمبلی به فرم چهار فیلد زیر نوشته می شوند: برچسب، نماد سمبليک، عملوندها و توضيحات.

[label] mnemonic [operand][;comment]

مثال.

MovInstruction: mov AX,BX ;this is a MOV instruction

برچسب (label) يک فيلد اختياری است که نامی را به دستوری اختصاص می دهد وامکان مراجعه و پرش به اين دستور را از دستورات ديگر فراهم می کند. برچسب ها به علامت کولن (:) ختم می شوند و در دستورات پرش به کرات استفاده خواهند شد(مثال1). يک برچسب می تواند حداکثر 31 کاراکتر باشد. کاراکترهای معتبر برچسب عبارتند از: حروف، ارقام و کاراکترهای $، _ و@. هستند. برچسب نبايد از کلمات کليدی باشد و با رقم شروع شود و کاراکتر نقطه تنها می تواند به عنوان اولين کاراکتر آن استفاده شود.

نماد (mnemonic) یک دستورالعمل زبان اسمبلی است.

فيلد عملوند (operand) مکان داده های مورد نياز پردازنده جهت انجام دستورالعمل مشخص شده در فیلد نماد را مشخص می کنند. هر دستورالعمل با توجه به عملکردش ممکن است شامل هيچ، يک يا دو عملوند باشد. در دستورات دو عملوندی، عملوند اول مقصد (destination) و عملوند دوم مبدا (source) ناميده می شوند(مثال2). فيلد عملوند در راهنماهای اسمبلر ممکن است شامل اطلاعات بيشتری هم (مانند Byteptr، Offset و ... ) باشد.

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

مثال1. استفاده از برچسب برای پرش.

              mov cx, 25
Loop1:   mov ax, cx
              call PrintInteger
              loop Loop1

مثال2. انواع دستورات صفر، یک و دو عملوندی.

nop                ;no operands -- does nothing
inc AX            ;one operand -- adds 1 to the contents of AX
add Word1,2 ;two operands -- adds 2 to the contents
                      ; of memory word WORD1

مثال3. توضیحات

; Initialize registers
   mov AX,0
   mov BX,0
   mov CX,0    ;CX counts terms, initially 0

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

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

386.

در ابتدای برنامه راهنمای 386. مشخص می کند که برنامه از دستورات و ثبات های 32 بیتی معرفی شده پردازنده 80386 استفاده می کند. می توانید از راهنماهای 486.، 586. یا 686. هم استفاده کنید. برای استفاده از کلیه دستورات اسمبلی پردازنده های پنتیوم پرو از راهنمای 686p. استفاده کنید.

model.

راهنمای model. مدل حافظه برنامه را مشخص می کند. عملوند اول مقابل آن برای تعیین اندازه اشاره گرهای کد و داده است و می تواند يکی از انتخاب های زير باشد. در برنامه های Win32 مدل حافظه flat مناسب تر است (توضیح بیشتر در بخش حافظه).عملوند مقابل آن می تواند يکی از انتخاب های زير باشد:

تعداد سگمنت کد تعداد سگمنت داده مدل حافظه
1-Tiny
11Small
بيشتر از يکی1Medium
1بيشتر از يکیCampact
بيشتر از يکیبيشتر از يکیLarge
آرايه های بزرگتر از 64KHuge
بدون سگمنت، تنها در مد محافظت شدهFlat

پارامتر دوم نحوه تبادل داده در فراخوانی زیربرنامه را تعیین می کند. می تواند C، Pascal یا Stdcall باشد. در توابع ویندوز تبادل پارمترها Stdcall است. به این معنی که پارامترهای از راست به چپ (به ترتیب عکس) وارد پشته می شوند.

مثال.

.model flat, stdcall

راهنماهای سگمنت

در بخش قبل توضیح دادیم که هر برنامه می تواند شامل يک يا چند سگمنت باشد. هر سگمنت توسط اشاره گرهایی که در ثبات های سگمنت قرار دارند ارجاع می شود. برنامه های exe. سه سگمنت را بايد داشته باشند: سگمنت داده برای ذخيره متغيرها، سگمنت کد برای دستورالعمل های اجرائی برنامه و سگمنت پشته برای نگهداری داده های موقتی، پارامترهای تابع و آدرس های برگشتی.

سگمنت ها در برنامه اسمبلی به روش های مختلفی تعریف می شوند. روش قدیمی استفاده از راهنماهای segment و ends است.

مثال. ساختار یک برنامه اسمبلی که از راهنماهای segment برای تعریف سگمنت های پشته، داده و کد استفاده کرده است.

SSeg segment PARA
   DW 32 dup(0)
SSeg ends
DSeg segment PARA
   ;declarations
DSeg ends
CSeg segment PARA
    Main proc
     ASSUME SS:SSeg, DS:DSeg, CS:CSeg
     mov AX,DSeg
     mov DS,AX
      ...
     mov AX,4c00h
     int 21h
    Main endp
CSeg ends
end Main

نکته. هرزمان نام سگمنت به عنوان عملوند در دستوری نوشته شود بلافاصله آدرس سگمنت جايگزين آن می شود.
نکته. ابتدای هر برنامه اسمبلی بايد آدرس سگمنت داده در ثبات DS قرار گيرد.

مثال. دستور زير آدرس سگمنت داده با نام dseg را در ثبات DS قرار می دهد.

mov AX, dseg     ;Loads AX with segment address of dseg.
mov DS, AX       ;Point ds at dseg.

راهنماهای stack. و data. و code. راهنماهای ساده شده سگمنت هستند که بجای راهنمای Segment برای تعیین محل شروع سگمنت های پشته، داده و کد بکار می روند.

سگمنت ها به ترتيبی که در برنامه تعريف شده اند در حافظه بار می شوند.

stack.

وقتی از راهنمای model. استفاده می کنید یک سگمنت برای پشته در نظرگرفته می شود. راهنمای stack. فضائی را برای پشته برنامه رزرو می کند. اندازه پشته در مقابل آن بر حسب بایت ذکر می شود. اگر عددی ذکر نشود پیش فرض 1024 بایت در نظر گرفته می شود.

.stack [size]

data.

راهنمای data. شروع سگمنت داده را تعیین می کند. تعریف و مقداردهی متغیرهای برنامه معمولا در این قسمت انجام می شود.

متغیر (variable) محلی در حافظه است که داده های برنامه در آنجا نگه داشته می شود. بخاطر تعداد کم ثبات ها متغیرها می توانند خیلی کارساز باشند. دو نوع متغیر وجود دارد: سراسری و محلی. متغیرهای سراسری آنهایی هستند که در سراسر سگمنت کد قابل دسترس هستند. متغیرهای محلی حافظه های موقتی هستند که درون تابع استفاده می شوند. وقتی ایجاد می شوند مقداردهی نمی شوند.

متغيرها را در هر سگمنتی می توان تعريف کرد اما اکثر برنامه نويسان همه آنها را در سگمنت داده تعريف می کنند. هر متغير به فرم کلی زير تعريف می شود:

VariableName Type InitialValue|?

Type نوع متغير را مشخص می کند که می تواند يکی از نوع های جدول زير باشد. InitialValue مقداراوليه متغير است. اگر نخواهيم مقدار اوليه بدهيم علامت سوال (?) می گذاريم. چند نوع متغیر که در آینده زیاد از آنها استفاده می کنیم byte، word و dword هستند که به ترتیب اندازه 1، 2 و 4 را بایت دارند.

تعداد بايتنوع
1byte/sbyte/db
2word/sword/dw
4dword/sdword/dd
8qword/dq
10tbyte/dt

متغیرها را می تواند با مقادیر عددی در مبناهای 10، 2 یا 16 مقداردهی کرد. به متغیری که مقداردهی نشده می توان با دستور mov در قسمت کد مقداری را نسبت داد.

مثال.

num db 64     ; Declare a byte, containing the value 64
var2 byte ?     ; Declare an uninitialized byte
X     dw ?        ; Declare a 2-byte uninitialized value
Y     DD 30000     ; Declare a 4-byte value, initialized to 30000
choice byte 'y'     ; Declare a byte value, referred to character 'Y'
neg_number word -12345      ; Declare a 2-byte value, initialized to -12345
real_num2     DQ 123.456      ; Declare a 8-byte value, initialized to 123.456

اسم متغیر یک شناسه است. شناسه (identifier)، سمبل ، يا برچسب اسمی است که به مقدار مشخصی نسبت داده می شود. اين مقدار می تواند آفستی در يک سگمنت، يک مقدار ثابت، يک آدرس سگمنت، آفستی درون يک رکورد يا حتی عملوند يک دستورالعمل باشد. در هر صورت شناسه امکان ارائه چيزی را با نام آشنا و قابل فهمی را می دهد.

نام شناسه از حروف، ارقام و کاراکترهای خاص تشکيل شده است. با محدوديت های زير:

• يک شناسه نمی تواند با يک رقم عددی شروع شود.
• يک اسم می تواند هر ترکيبی از حروف بزرگ و کوچک باشد. اسمبلر با حساس به متن نيست.
• يک شناسه ممکن است هر تعداد کاراکتری باشد ولی تنها 31 کاراکتر اول آن استفاده می شود. اسمبلر کاراکترهای بعدی را نديده می گيرد.
• کاراکترهای _، $، ? و @ ممکن است درون يک سمبل ظاهر شوند. البته کارکترهای $ و? خاص هستند و نمی توانيد شناسه را منحصرا با اين کاراکترها بسازيد.
• يک شناسه نمی تواند از اسامی رزرو شده باشد. دستورالعمل های 80x86 و نام ثبات ها رزرو شده هستند.

مثال. چند شناسه مجاز.

Item1   Bletch   RightHere   Right_Here
__Special   $1234   @Home Dollar$
WhereAmI?   @1234   .TEST SUM_OF_DIGITS

مثال. بعضی شناسه های غيرمجاز.

1TooMany   Hello.There   $
LABEL Right Here Hi,There

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

بدست آوردن آدرس متغیر

دربرنامه های 1 و 2 بالا از راهنمای addr برای بدست آوردن آدرس متغیر message استفاده شده است. راهنمای دیگر برای اینکار offset است. هدف هردو راهنمای مشابه هستند تفاوت آنها در این است که offset تنها می تواند آدرس متغیرهای سراسری را بدست بیارد ولی addr می تواند آدرس متغیرهای سراسری و محلی هردو را بدهد.

آدرس متغیر در بعضی جاها مثل ارسال پارامتر به زیربرنامه لازم می شود. دربرنامه های 1 و 2 بالا از راهنمای addr برای بدست آوردن آدرس متغیر message استفاده شده است. راهنمای دیگر برای اینکار offset است. هدف هردو راهنمای مشابه هستند تفاوت آنها در این است که Offset تنها می تواند آدرس متغیرهای سراسری را بدست بیارد ولی addr می تواند آدرس متغیرهای سراسری و محلی هردو را بدهد.

از دستور Lea هم برای بدست آوردن آدرس متغیر می توان استفاده کرد که قوی تر از offset است چون اجازه می دهد آدرس متغیرهای اندیس دار را هم بگیرید (مطالعه بیشتر در مبحث آرایه) .

مثال. اختصاص دادن آدرس متغیر var1 به ثبات BX.

lea      BX, var1                   ; get address of VAR1 in BX.
mov    Byte Ptr [BX], 44h    ; modify the contents of VAR1.

مثال. دراینجا از Offset به جای LEA استفاده شده.

mov    BX, OFFSET var1      ; get address of VAR1 in BX.
mov    Byte Ptr [BX], 44h    ; modify the contents of VAR1.

هر دو دستور mov BX,OFFSET var1 و lea BX,var1 یک کار را انجام می دهند یک عدد 16 بیتی آفست متغیر را در ثبات BX ذخیره می کنند و هردو به یک دستور زبان ماشین ترجمه می شوند.

?data.

متغیرها اگر مقداردهی شوند در قسمت data. جای می گیرند. متغیرهایی که مقداردهی نمی شوند را در قسمت ?data. می توان تعریف کرد.

const.

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

ثابت های واقعی ثابتهایی هستند که مقدارشان صريحا ذکر شده است ودارای انواع مختلفی از جمله صحيح، حقيقی، رشته هستند.

مثال. چند مقدار ثابت.

123
3.14159
"Literal String Constant"
0FABCh
'A'

ثابت های عددی می توانند در مبنای 2، 10 يا 16 نوشته شوند. برای مشخص کردن مبنای عدد از پسوندهای جدول زير استفاده می شود. اگر مبنا صريحا ذکر نشود پيش فرض مبنای 10 است.

مبناپسوند
BinaryB يا b
decimalD يا d يا T يا t
hexadecimalH يا h

مثال. ثابت های عددی.

0F000h
12345d
0110010100b

ثابت های رشته ای درون گيومه (") يا تک گيومه (') قرار می گيرند.

مثال. ثابت های رشته ای.

"This is a string"
'So is this'
'Doesn''t this look weird?'
"Doesn't this look weird?"
"Microsoft claims ""Our software is very fast."" Do you believe them?"
'Microsoft claims "Our software is very fast." Do you believe them?'

ثابت نامدار مانند متغیرهایی هستند که مقدارشان تغییر نمی کند. به صورت کلی زير تعريف می شوند:

ConstantName EQU Value|Expression
ConstantName = Value

ConstantName نام ثابت است و Value مقداری است که به ثابت اختصاص داده می شود.

نکته. علامت مساوی تنها برای مقدارهای عددی بکار می رود.

مثال.

One         equ 1
Minus1    equ -1
TryAgain equ 'Y'
String      equ "Hello there"
Num = 16
Size = Count * Element

code.

راهنمای code. شروع سگمنت کد را تعیین می کند. دستورالعمل های برنامه در سگمنت کد قرار می گيرند. کد معمولا شامل چند زیربرنامه است.

راهنمای end انتهای سگمنت کد و پايان برنامه را برای اسمبلر مشخص می کند.

برای پايان اجرای برنامه و بازگشت به محيط سيستم عامل در انتهای هر برنامه تابع 4c از وقفه 21h یا تابع ExitProcess از توابع Win32 بايد فراخوانی شود.

مثال. فراخوانی تابع 4ch از وقفه 21h.

Mov AX,4c00h
Int 21h

End

راهنمای end انتهای برنامه را مشخص می کند.

END address

عملوندی که در مقابل آن ذکر می شود نقطه آغاز اجرا يا نام تابع اصلی برنامه را به سيستم عامل می گويد و در واقع ثبات های CS و IP را تنظيم می کند. اگر اين عملوند نباشد سيستم عامل از اولين بايت سگمنت کد شروع به اجرا می کند. نقطه شروع الزاما بلافاصله بعد از راهنمای .code نيست.

مثال. شروع اجرا از برچسب start.

Start: ... ;your code here ... End Start

Include

راهنمای include کدهای فایل منبع که نام آن ذکر شده است را به کد فایل فعلی اضافه می کند. دستور include به صورت زیر نوشته می شود:

INCLUDE filename

مثال.

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc

Includelib

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

INCLUDELIB libraryname

مثال.

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

Invoke

راهنمای invoke مخصوص Masm است و برای فراخوانی توابع بدون اجبار به اضافه کردن پارامترهای تابع در پشته بکار می رود.

INVOKE expression , arguments

عملوند اول آن نام زیربرنامه ای است که فراخوانی می کند و پارامترهای تابع پشت سر آن نوشته می شود. پارامترها می توانند به صورت یک عبارت، ثبات، یا آدرس (همراه با ADDR) ارسال شوند.

مثال. فراخوانی تابع StdOut از توابع Masm32 برای نمایش پیغام و ارسال آدرس متغیر message.

invoke StdOut, addr message

مثال. فراخوانی تابع ExitProcess برای خاتمه برنامه و ارسال کد 0 به معنی اجرای موفق برنامه به سیستم عامل.

invoke ExitProcess, 0

Option

راهنمای option ویژگی هایی را در اسمبلر فعال یا غیرفعال می کند.

مثال. اعمال حساسیت به متن یعنی بین حروف بزرگ و کوچک تفاوت قایل می شود. مثلا hello و Hello در برنامه متفاوت از هم دیده می شوند.

option casemap :none

Extern

راهنمای extern زیربرنامه هایی را که در فایل دیگری قرار دارند و در این فایل ارجاع می شوند را تعیین می کند.

Proc

هر برنامه معمولا شامل چند زیربرنامه می شود. راهنماهای proc و endp شروع و پایان زیربرنامه را تعیین می کنند. برای توضیحات بیشتر بخش زیربرنامه را مطالعه کنید.

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

proc_name PROC
. . .
Ret
Proc_name ENDP

مدهای آدرس دهی

اکثر دستورات اسمبلی به عملوندی برای پردازش احتیاج دارند. بعضی از دستورالعمل ها عملوندی احتیاج ندارند، بعضی به یک، دو یا سه عملوند احتیاج دارند. آدرس عملوند محل داده ای که باید پردازش شود را مشخص می کند. يکی از مهمترين وظايف يک دستورالعمل تعيين آدرس عملوندهايش است. روش های دستيابی به عملوندها را آدرس دهی می نامند.

سه مد آدرس دهی اصلی وجود دارد:

• آدرس دهی فوری
• آدرس دهی ثباتی
• آدرس دهی حافظه

آدرس دهی ثباتی

در این مد آدرس دهی یک از ثبات ها عملوند دستور را نگه می دارد. پردازنده عملوند را از يک ثبات دريافت می کند يا به آن تحويل می دهد. ثبات ممکن است اولین، دومین یا هردو عملوند دستور باشد. پردازش بین دو ثبات که حافظه را درگیر نمی کند سریعترین حالت پردازش داده است.

مثال.

mov DX, TAX_RATE    ; Register in first operand
mov COUNT, CX        ; Register in second operand
mov EAX, EBX            ; Both the operands are in registers

آدرس دهی فوری

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

مثال.

BYTE_VALUE db 150     ; A byte value is defined
add BYTE_VALUE, 65     ; An immediate operand 65 is added
mov AX, 45H        ; Immediate constant 45H is transferred to AX

آدرس دهی حافظه مستقيم

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

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

نکته. تنها یکی از عملوندها می تواند در مد حافظه ای باشد.
نکته. این مد آدرس دهی از عملیات ریاضی برای تغییر آدرس بهره می برد.

مثال.

mov AX,[0004]
add BYTE_VALUE, DL           ; Adds the register in the memory location
mov BX, WORD_VALUE        ; Operand from the memory is added to register

آدرس دهی غير مستقيم با ثبات

در این مد آدرس دهی مقدار داده در داخل حافظه قرار دارد و آدرس آن در داخل يکی از ثبات های EBX، EBP (BP,BX) یا ثبات های ایندکس ESI و EDI قرار می گیرند که در دستورالعمل داخل کروشه ذکر می شود.

نکته. دقت کنید که تنها ثبات های EBX، EBP، ESI و EDI (یا BX، BP، SI و DI) می توانند درون کروشه نوشته شوند. نکته. آدرس دهی غیرمستقیم برای متغیرهایی که چند عضو دارند مانند آرایه ها استفاده می شوند.

مثال. آدرس شروع آرایه در ثبات EBX ذخیره شده. بقیه عناصر آرایه توسط EBX دسترسی می شوند.

MY_TABLE DW 10 dup (0) ; Allocates 10 words (2 bytes) each initialized to 0

lea EBX, MY_TABLE
mov EBX, [MY_TABLE]   ; Effective Address of MY_TABLE in EBX
mov [EBX], 110             ; MY_TABLE[0] = 110
add EBX, 2                    ; EBX = EBX +2
mov [EBX], 123             ; MY_TABLE[1] = 123

آدرس دهی حافظه ای نسبی

در آدرس دهی نسبی داده در حافظه قرار دارد و آدرس آن از جمع مقادير یکی از ثبات های EBX، EBP، ESI و EDI (یا BX، BP، SI و DI) و يک مقدار ثابت بدست می آيد.

مثال.

mov AX,[DI+4]
mov AX,[BP+SI+4]

عملگرهای اندازه

در مواردی که اندازه عملوندهای حافظه ای نامشخص است (مثل زمانی که عملوند دیگر فوری است) از راهنماهای Byte Ptr، Word Ptr و DWord Ptr برای تعیین اندازه داده درون حافظه مورد دسترس استفاده می شود. در دستوراتی دو عملوندی که یک عملوند ثبات و دیگری حافظه است اندازه ثبات تعداد بایت های ارجاع شده حافظه را تعیین می کند بنابراین نیازی به راهنما برای تعیین اندازه نیست.

مثال. در دستور زیر اسمبلر اطلاعی از اندازه حافظه ای که ESI اشاره می کند ندارد. مقدار داده فوری کمکی نمی کند چون عدد 5 می تواند به صورت یک 0005h در یک متغیر word یا 00000005h در یک متغیر double word ذخیره شود. اسمبلر در مواجهه با این دستور خطا تولید می کند.

mov [ESI], 5

مثال. استفاده از عملگرها برای تعیین اندازه حافظه.

mov byte ptr [ESI], 5        ;For a byte variable
mov word ptr [ESI], 5       ;For a word variable
mov dword ptr [ESI], 5     ;For a dword variable


لیست دستورات پایه اسمبلی

ليست اسامی رزرو شده ماکرواسمبلر ورژن 6.0


دانلود PDF این درس


 


 

صفحه اصلی| درباره| تماس