add
دستورالعمل ADD ( عملگر جمع در زبان اسمبلی )
Usage: ADD dest,src
روش بکارگیری : از چپ به راست : دستور ADD ؛ عملوند مقصد (dest ) ، عملوند مبدا (src)
Modifies flags: AF CF OF PF SF ZF
دستور ADD پرچمهای AF و CF و OF و PF و SF و ZF را تغییر می دهد .
Adds 'src' to 'dest' replacing the original contents of 'dest'.
دستور add ، محتویات عملوندهای مبدا و مقصد را با هم جمع می کند و سپس نتیجه را جایگزین محتویات قبلی عملوند مقصد ، می نماید . یعنی رونویسی می کند .
نکته : دستور add در زبان اسمبلی با عملگر + در سایر زبانها مطابقت کامل دارد . درواقع کار این دستور اینست که خیلی ساده ، محتویات درون دو عملوند مبدا و مقصد را با یکدیگر جمع کرده و حاصل جمع را به درون عملوند مقصد ، ارسال می کند .
Add Integers
دستور add بعنوان عملگر جمع ، اعداد صحیح را با یکدیگر جمع می کند .
رمزگشایی :
در تمام موارد زیر و سایر موارد مشابه باید به این نکات توجه کرد :
1- r و reg هردو به معنای register ( ثبات - ثبت کننده ) می باشد که منظور همان رجیسترهای درون پردازنده است .
2- m مخفف memory می باشد . یعنی مکان حافظه یا یک آدرس از حافظه . منظور از حافظه در اینجا می تواند حافظه ی رم باشد زیرا تمام نرم افزارها به محض اجرا به درون حافظه ی رم بارگیری می شوند و پردازنده ، محتویات درون نرم افزار را ازطریق حافظه ی رم می خواند .
اما در مواردی که با ادرس فیزیکی و دقیق یک عنصر در درون یک نرم افزار یا کتابخانه سروکار داشته باشیم انوقت منظور از حافظه ، هارد دیسک و سایر حافظه های فرعی و همیشگی می باشد .
نکته : حافظه ی اصلی کامپیوتر شامل رجیسترهای پردازنده، حافظه ی کش درون پردازنده ، حافظه ی رم و حافظه ی رام می باشد .
حافظه ی فرعی کامپیوتر شامل نوار مغناطیسی ( شبیه حلقه های فیلم دستگاه آپارات که توسط آپاراتچی نصب می شود ) که در دهه های 50 تا 70 میلادی در کامپیوترها بکار می رفته است ) ، کارت پانچ ( شبیه به دستگاه حضور و غیاب در برخی ادارات که باید کارت را سوراخ کرد . کارت پانچ در دهه های 30 تا 50 میلادی بعنوان قدیمی ترین شکل حافظه ، برای برنامه نویسی با زبان ماشین ، بکار می رفته است . ) ، فلاپی دیسک . هارد دیسک . دیسک جامد . لوح نوری . فلش مموری و سایر انواع حافظه های جانبی می باشد .
نکته ی ظریف : در برنامه نویسی با تمام زبانهای سطح بالا و سطح پایین ( بجز زبان ماشین ) منظور از حافظه ، همان حافظه ی رم می باشد .
اما در برنامه نویسی با زبان ماشین که با کمک هگز ادیتور انجام می شود منظور از حافظه هم حافظه ی رم می باشد و هم حافظه ی فرعی کامپیوتر و محتویات درون نرم افزار یا فایلهای کتابخانه که روی هارد یا فلاپی یا سایر انواع حافظه قرار دارد .
زیرا در برنامه نویسی با زبان ماشین ما مستقیما با معماری خود نرم افزار سروکار داریم لذا با انواع ادرسها درگیر می شویم و درنتیجه منظور از حافظه در زبان ماشین ، حافظه ی روی هارد دیسک است .
این موضوع یعنی برنامه نویسی با هگز ادیتور تاکنون در هیچ سایت ایرانی یا خارجی مطرح نشده است و من برای اولین بار قصد دارم در اینده ، این موضوع را عملا به همه نشان دهم .
هرچیزی که در سمت راست کاراکتر ; نوشته می شود اصطلاحا کامنت یا توضیح نامیده می شود . به این کاراکتر ، اصطلاحا سمی کالن ( semicolon = نصف کالن ) گفته می شود . سمی ( semi ) یعنی نصف .
کالن (Colon) همان علامت دو نقطه یعنی : می باشد .
برای تایپ کردن کاراکتر سمی کالن ، کافیست در حالت انگلیسی ؛ کلید مربوط به حرف ک را فشار دهیم . به همین راحتی .
به سمی کالن اصطلاحا نقطه ویرگول نیز گفته می شود . البته ویرگول یک اصطلاح فارسی است و شکل اش دقیقا عکس کاما می باشد .
ویرگول یعنی ، که در ویندوز از فشردن کلیدهای ترکیبی Shift+T بدست می آید .
نقطه ویرگول یعنی ؛ که از فشردن کلیدهای ترکیبی Shift+Y بدست می آید .
نقطه ویرگول در زبان فارسی به ندرت استفاده می شود و دارای مکث طولانی تری نسبت به ویرگول می باشد .
من خودم شخصا از ویرگول استفاده می کنم و کمتر پیش می آید که از نقطه ویرگول استفاده نمایم .
البته اینها به زبان فارسی معمولی ویندوز مربوط می شود که دقیقا با چینش و آرایش حروف فارسی کیبوردهای فیزیکی مطابقت دارد و فارسی استاندارد واقعی و حقیقی است که کاملا با استانداردهای ویندوز و کیبوردهای ویندوزی سازگار است .
در فارسی به اصطلاح استاندارد که سابقه اش به قبل از انقلاب می رسد و بعد از انقلاب نیز برای سهولت کار تایپیستهای قدیمی ( ماشین تحریر ) چندین بار مطرح شد و توسط گروهی از متعصبین بی مغز ایرانی و فاقد سواد کامپیوتری ، به زور وارد لینوکس و مک و سپس ویندوز گردید عملا یک چینش عجیب و غریب و نامانوس با عنوان غلط انداز " فارسی استاندارد " بر کاربران تحمیل شد .
من خودم شخصا از فارسی استاندارد استفاده نمی کنم چون اصلا و ابدا به درد تایپ نمی خورد و یک چیز مسخره و جفنگ است . فارسی استاندارد توسط یک مشت بیسواد و متعصب و میهن پرست مطرح و ترویج شد که البته سواد کامپیوتری خصوصا سواد تایپ در ویندوز را نداشتند و می خواستند چرخ را از نو اختراع کنند . من همیشه و تا ابد از فارسی معمولی و قدیمی ویندوز استفاده می کنم و کاملا راضی هستم چون با چینش حروف فارسی کیبورد فیزیکی ، کاملا تطابق و سازگاری دارد . من از سال 1378 شمسی تا الان ( سال 1400 شمسی ) سالهاست که شبانه روز با زبان فارسی معمولی ویندوز ، تایپ کرده ام و تا ابد نیز با همین فارسی معمولی ویندوز تایپ خواهم کرد و هرگز به سمت فارسی استاندارد نخواهم رفت .
فارسی استاندارد به درد کیبورد کامپیوتر نمی خورد و یک چیز زائد و اضافی است که توسط افراد متعصب ، به سیستم عاملها وارد گردید و من اصلا و ابدا آنرا قبول ندارم . زیرا تایپ کردن با فارسی استاندارد یک شکنجه و خودآزاری محسوب می شود .
من ترجیح می دهم از صفحه کلید فارسی معمولی ویندوز استفاده نمایم . چون در فارسی معمولی ویندوز جای حروف فارسی دقیقا همان جایی است که کیبورد فیزیکی به من نشان می دهد . در جایگاه یک تایپیست ، بطور کامل با صفحه کلید فارسی استاندارد ، مخالف هستم و انرا نوعی بدعت می دانم . لذا هرگز از این فارسی به اصطلاح استاندارد که نوعی بدعت می باشد استفاده نمی کنم .
بگذریم .....
کاراکتر / را می توان بعنوان " یا " قلمداد کرد .
مثلا در عبارات زیر منظور از r/m8 این است : رجیستر یا حافظه ی 8 بیتی .
ADD r/m8,reg8 ; 00 /r [8086]
متاسفانه سهل انگاری طراحان اسمبلرها و مبلغان زبان اسمبلی، تا به امروز مانع از فهم این عبارات شده است . لذا رمزگشایی از این عبارات ، یک کار بسیار دشوار می باشد ( لااقل برای من که فقط یک تایپیست ساده هستم رمزگشایی از این عبارات ، خیلی دشوار است و ممکن است ناخواسته دچار اشتباه شوم ) .
دستور add اگر با رجیستر و حافظه ی 8 بیتی سروکار داشته باشد ، پس از کامپایل شدن به کد هگز 00 تبدیل می شود .
/ یعنی " یا "
این به پردازنده های بسیار قدیمی هشت بیتی اینتل مربوط می شود . مثل پردازنده ی اینتل 4004 یا هر پردازنده و میکروکنترولر 8 بیتی خانواده ی اینتل .
ولی خب ، می توان انرا روی پردازنده های 16 بیتی و 32 بیتی و 64 بیتی نیز اجرا کرد .
اما باید دانست که زبان اسمبلی پردازنده های قبل از 8086 با پردازنده های بعد از 8086 تا حدودی متفاوت است . این تفاوت البته کامل و صد درصدی نیست و یکسری شباهتها نیز وجود دارد .
در مجموع اگر کد مربوط به پردازنده های 8 بیتی را نتوانستید روی پردازنده ی 32 بیتی یا 64 بیتی اجرا کنید کاملا طبیعی است .
مثلا در زبان اسمبلی پردازنده ی اینتل 8080 ، دستور nop به جای اینکه به کد هگزادسیمال 90h تبدیل شود به کد هگزادسیمال 00h تبدیل می شود .
هرچند برای هر دستور زبان اسمبلی اینتل خانواده ی ایکس 86 ( پردازنده های مدرن امروزی ) نیز می توانیم چندین کد زبان ماشین تولید نماییم . اما باید به دنبال صحیح ترین کد باشیم . زیرا برخی از این کدهای هگز عملا مشکلاتی دارند و برنامه را دچار هنگ و کرش می نمایند .
اصولا امروزه در هیچ کامپیوتر نمی توانیم پردازنده ی اینتل 8 بیتی پیدا کنیم زیرا منسوخ شده است .
البته امروزه نیز پردازنده ها و میکروکنترلرهای 8 بیتی اینتل در برخی جاها مثلا در کنار موتورخانه یا دیزل ژنراتور یک بیمارستان هنوز بکار می رود .
برای فهم بهتر این کدها باید از هگز ادیتورها کمک بگیریم . برنامه ی C32asm می تواند به ازای هر کد اسمبلی ، چندین کد هگز تولید کند . اما شما باید فقط آن کد هگز را که با انکودر اسمبلر RosAsm یعنی ابزار encoding مطابق می باشد را در برنامه ی C32asm بکار گیرید . زیرا برخی از کدهایی که برنامه ی C32asm تولید می کند باعث هنگ کردن سیستم می شوند و خطرناک هستند .
بنابراین باید از RosAsm و ابزار Encoding اش کمک بگیریم .
ابزار Encoding اسمبلر RosAsm را می توانید از منوی Tools پیدا کنید .
در باکس بالایی این ابزار ، دستور اسمبلی را بنویسید و کلید Enter را فشار دهید تا کد هگز واقعی را در باکس پایینی به شما نشان دهد .
اسرار هگز ادیتورها را کمتر کسی به شما می گوید . من اگر خدا بخواهد در آینده ی نزدیک قصد دارم اسرار هگز ادیتورها و روش برنامه نویسی با هگز ادیتور را برملا کنم تا متوجه شوید که طراحان کامپایلرهای زبانهای سطح بالا و البته مایکروسافت و اینتل چه جنایاتی در حق کاربران ویندوز مرتکب شده اند .
ADD r/m16,reg16 ; o16 01 /r [8086]
دستور add اگر با رجیستر 16 بیتی سروکار داشته باشد به کد اوکتال 1601 تبدیل می شود .
حرف o در عبارت بالا مخفف octal می باشد . اوکتال یعنی اعداد 0 تا 7 که روی هم 8 کاراکتر را تشکیل می دهند . اوکتال یعنی هشت تایی .
/ یعنی " یا "
نکته بسیار مهم :
من شخصا از این عبارات نامفهوم و مضحک از قبیل : دهدهی ، هشت هشتی ، دودویی ، شانزده شانزدهی ؛ متنفر هستم و نمی دانم کدام دیوانه ای این عبارات احمقانه و جفنگ را اختراع کرده و در تمام متون اموزش برنامه نویسی و در سرتاسر وب و البته در تمام دیکشنری ها ، رایج کرده است؟؟؟؟
خب چرا مثل بچه ی آدم نمی گویید : ده تایی ، هشت تایی ، دو تایی ، شانزده تایی ؟؟؟
واقعا چه دلیل دارد که یک کلمه را دوبار تکرار می کنید و بدبختانه در تمام متون آموزشی نیز از این کلمات قلمبه سلمبه استفاده می نمایید ؟؟؟ . جای تاسف است .
عبارت دودویی آدم را به یاد ورزش دو میدانی می اندازد !!!
والاه . یک مشت دیوانه ، این کلمات احمقانه را باب کرده اند . اینها باید اصلاح شوند :
بجای کلمه ی مضحک دودویی خیلی راحت بگویید : دوتایی .
بجای کلمه ی مضحک دهدهی ، خیلی راحت بگویید : ده تایی .
بجای کلمه ی مضحک شانزده شانزدهی ، خیلی راحت بگویید : شانزده تایی
بجای کلمه ی مضحک هشت هشتی ، خیلی راحت بگویید : هشت تایی .
اصلا معلوم نیست کدام بیمار روانی اولین بار این کلمات جفنگ و خنده دار و نامفهوم را در فرهنگ فارسی برنامه نویسان وارد کرده است . خدا از سر تقصیرات اش بگذرد و اگر از دنیا رفته خدا رحمت اش کند که مانع فهم خیلی مسائل شده است .
ADD r/m32,reg32 ; o32 01 /r [386]
دستور add اگر با رجیستر 32 بیتی و حافظه ی 32 بیتی سروکار داشته باشد به کد اکتال ( هشت تایی ) 3201 تبدیل می شود که می توانید با کمک یک هگز ادیتور این کد را در مبنای اکتال ( هشت تایی ) با چشم ببینید .
حرف o مخفف octal و به معنای سیستم عددی هشت تایی می باشد . یعنی اعداد 0 تا 7 .
386 یعنی اینکه این کد فقط روی پردازنده ی اینتل 80386 و بالاتر اجرا می شود و روی پردازنده های پایین تر از 80386 اجرا نمی شود . بالاتر یعنی جدیدتر و مدرن تر . پایین تر یعنی قدیمی تر .
البته بسیاری از پردازنده های مدرن امروزی براساس پردازنده ی 80386 ساخته شده اند .
فقط این حرف r آخری را هنوز نتوانستم رمزگشایی نمایم !!
/ یعنی " یا "
ADD reg8,r/m8 ; 02 /r [8086]
دستور add اگر با رجیستر 8 بیتی و رجیستر/حافظه ی 8 بیتی بکار رود به کد 02 تبدیل می شود .
/ یعنی " یا "
ADD reg16,r/m16 ; o16 03 /r [8086]
دستور add اگر با رجیستر 16 بیتی و رجیستر / حافظه ی 16 بیتی بکار رود به کد اوکتال 1603 تبدیل می شود .
/ یعنی " یا "
ADD reg32,r/m32 ; o32 03 /r [386]
دستور add اگر با رجیستر 32 بیتی و رجیستر / حافظه ی 32 بیتی بکار رود به کد اوکتال 3203 تبدیل می شود .
/ یعنی " یا "
ADD r/m8,imm8 ; 80 /0 ib [8086]
دستور add اگر با رجیستر / حافظه ی 8 بیتی و عدد فوری 8 بیتی بکار رود به کد 80 تبدیل می شود .
ib یعنی عدد فوری در اندازه ی بایت
b = بایت
0 = عدد صفر ( البته احتمالا همان عدد فوری است که در اینجا صفر می باشد)
/ یعنی " یا "
ADD r/m16,imm16 ; o16 81 /0 iw [8086]
دستور add اگر با رجیستر /حافظه ی 16 بیتی و عدد فوری 16 بیتی بکار رود به کد اوکتال 1681 تبدیل می شود .
iw = عدد فوری در اندازه ی ورد
w = word
word یعنی دو بایت یعنی 16 بیت
0 = عدد صفر ( البته احتمالا همان عدد فوری است که در اینجا صفر می باشد)
/ یعنی " یا "
این ورد را با عبارت word که به معنای : لغت می باشد اشتباه نگیرید . این ورد یعنی اینکه دو بایت پشت سرهم قرار گیرند . یعنی مجموع 16 بیت از فضای حافظه .
هر بایت یعنی 8 بیت .
ADD r/m32,imm32 ; o32 81 /0 id [386]
دستور add اگر با رجیستر /حافظه ی 32 بیتی و عدد فوری 32 بیتی بکار رود به کد اوکتال 3281 تبدیل می شود .
id یعنی عدد فوری در اندازه ی دی ورد
دی ورد یا dword یعنی دوتا ورد یعنی 4 تا بایت یعنی 32 بیت
d یعنی double یعنی دوتایی دوگانه . دولایه . دوبرابر . دولا .
dword یعنی 32 بیت .
0 = عدد صفر ( البته احتمالا همان عدد فوری است که در اینجا صفر می باشد)
/ یعنی " یا "
ADD r/m16,imm8 ; o16 83 /0 ib [8086]
b یعنی byte
i یعنی عدد فوری
0 = عدد صفر ( البته احتمالا همان عدد فوری است که در اینجا صفر می باشد)
/ یعنی " یا "
ADD r/m32,imm8 ; o32 83 /0 ib [386]
b یعنی byte
i یعنی عدد فوری
0 = عدد صفر ( البته احتمالا همان عدد فوری است که در اینجا صفر می باشد)
/ یعنی " یا "
ADD AL,imm8 ; 04 ib [8086]
b یعنی byte
i یعنی عدد فوری
دستور add اگر با رجیستر AL و عدد فوری 8 بیتی بکار رود به کد 4 تبدیل می شود که احتمالا همان عدد فوری می باشد .
ADD AX,imm16 ; o16 05 iw [8086]
iw یعنی عدد فوری در اندازه ی Word
word یعنی 2 بایت پشت سرهم
بایت = هشت بیت
بیت = 0 یا 1
دستور add اگر با رجیستر AX ( که 16 بیتی می باشد ) و عدد فوری 16 بیتی بکار رود به کد اوکتال 1605 تبدیل می شود .
ADD EAX,imm32 ; o32 05 id [386]
id یعنی عدد فوری در اندازه ی دی ورد
دی ورد = دو تا ورد
ورد = دو تا بایت پشت سرهم
بایت = هشت بیت
بیت = 0 و 1
دستور add اگر با رجیستر 32 بیتی eax و عدد فوری 32 بیتی بکار رود به کد اوکتال 3205 تبدیل می شود .
ADD performs integer addition: it adds its two operands together, and leaves the result in its destination (first) operand. The destination operand can be a register or a memory location. The source operand can be a register, a memory location or an immediate value.
دستور add عملیات جمع بین دو عدد صحیح را اجرا می کند . این دستور ، دو عملوند اش را با یکدیگر جمع می کند ، و باقی می گذارد نتیجه را در عملوند مقصد ( اولین عملوند از سمت چپ به راست ) . عملوند مقصد ( اولین عملوند از سمت چپ ) می تواند یک رجیستر یا مکان حافظه باشد . عملوند مبدا می تواند یک رجیستر یا یک مکان حافظه یا یک عدد فوری باشد
The flags are set according to the result of the operation: in particular, the carry flag is affected and can be used by a subsequent ADC instruction.
رجیسترهای پرچم براساس نتیجه ی عملیات ، تنظیم می شوند : بطور خاص ، پرچم انتقال تحت تاثیر قرار گرفته است و می تواند بوسیله ی یک دستور adc که بعدا می آید بکار گرفته شود .
+
یک مثال از کاربرد دستور add در اسمبلر RosAsm :
main:
std ; set direction flag
Do ; macro
mov al bl | and al 0F | add al '0'
On al > '9', add al 7 ; on = macro
stosb | shr ebx 4
Do_Loop ; Do_Loop = macro
cld ; clear direction flag
ret
نکته : دستوراتی همچون stosb و shr را در پست مربوطه تفسیر و تشریح خواهم کرد . انشاء ا...
+
نکته : از پست بعد ، برای جلوگیری از اتلاف وقت ، از رمزگشایی چیزهای تکراری خودداری می کنم و به اصل موضوع یعنی کاربرد هر دستور زبان اسمبلی می پردازم . انشاء ا...
+
وحید محمدی - وبلاگ وحیدمی