روسسم

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

روسسم

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

وبلاگ روسسم مکانی برای تدریس اسمبلر روسسم می باشد. کپی برداری از مطالب وبلاگ روسسم بلامانع است.http://rosasm.blog.ir محبوبه زرین

طبقه بندی موضوعی
کلمات کلیدی
بایگانی
آخرین مطالب
پربیننده ترین مطالب
محبوب ترین مطالب
نویسندگان

بنام خدا:




ادامه ی تفسیر برنامه ی  td002Wave :




همانطور که در پست قبلی قول داده بودم قرار شد که باقیمانده ی سورس برنامه ی td002Wave را  در پستی جداگانه تفسیر کنم .


+


حالا ادامه ی تفسیر کد برنامه ی  td002Wave را شروع می کنم :




cbWndExtra:    D$ 0


رهنمود کلاس بایتهای اضافی ،  فایل  rc   .

در این مورد بعدا اگر فرصتی پیش آمد توضیح می دهم .


hInstance:     D$ 0


در این عبارت، مقدار   hInstance که دستگیره ی برنامه ی ماست برابر با صفر می شود. این دستگیره  با تابع  GetModuleHandleA رابطه ی تنگاتنگ و نزدیک دارد .


hIcon:         D$ 0


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


لازم به ذکر است که اینها  بخشی از  ساختار  WndClassEx  می باشند .


hbrBackground: D$ 2


این عبارت نوع رنگ  بک گراند پنجره ی اصلی برنامه  را تعیین می کند .



lpszMenuName:  D$ 0


این عبارت ، نام کلاس منو در فایل ریسورس را نعیین می کند .



lpszClassName: D$ 0


نام کلاس پنجره ی اصلی برنامه و پنجره های فرعی اش .




 hIconSm:       D$ 0



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


+

+

+

خب حالا به ساختار  MSG می رسیم که توسط تابع  GetMessageA  بکار گرفته می شود :


hWnd:          D$ 0

دستگیره ی پنجره ای که پیامها را دریافت می کند .


message:       D$ 0


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




wParam:        D$ 0


اطلاعات اضافی دررابطه با پیامهای پنجره ی برنامه . (پارامتر پنجره ) .



lParam:        D$ 0


اطلاعات اضافی دربارهی پیامهای پنجره  ( پارامتر طولانی) .


time:          D$ 0


مقدار زمان لازم برای  پست شدن  پیام  به سیستم .


 xpt:           D$ 0


مکان ایکس  کرسر ماوس .   ساختار  POINT 


ypt:           D$ 0


مکان ایگرگ  کرسر ماوس  .  ساختار  POINT   


=========

=========


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

+

+

+

حالا می رسیم به تفسیر کد اصلی برنامه :





Main:


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


 push  0        

                    

دستور push 0  دستگیره ی ماژول برنامه را دریافت می کند .  عدد 0 یعنی دریافت دستگیره ی برنامه . دستگیره یعنی دستگیره ی پنجره ی اصلی برنامه . دستور push  در زبان اسمبلی کاربردهای مختلف دارد از جمله معرفی کردن متغیرها و ثابتها به سیستم و دریافت برخی عناصر و پارامترها مثل دستگیره ی پنجره ی اصلی یا فرعی برنامه ی ویندوزی و سایر موارد . همچنین از دستور  push  برای ذخیره کردن موقتی محتویات درون رجیسترهای  پردازنده  نیز استفاده می شود.  خلاصه اینکه دستور push  یکی از پرکاربردترین دستورات زبان اسمبلی می باشد .  کلمه ی push  به معنای هل دادن می باشد . یعنی هل دادن یک چیزی به درون پشته یا هر جای دیگری .  در دستور بالا  ،  ;lpModuleHandle  که همان دستگیره ی ماژول برنامه است به سیستم معرفی می شود .



    call  'KERNEL32.GetModuleHandleA'  


دستور بالا   تابع  GetModuleHandleA  را احضار می کند . پسوند A در انتهای نام این تابع به معنای  Ascii می باشد . یعنی برای مواردیکه بخواهیم برنامه هایی مبتنی بر سیستم کدگذاری  Ansi  بنویسیم .  اگر  بجای  A  از  حرف  W  در انتهای نام این تابع و سایر توابع API ویندوز استفاده شود آنوقت می توانیم برنامه هایی کاملا یونیکد و سازگار با زبانهای یونیکد مثل زبان فارسی را در زبان اسمبلی بنویسیم .

============





   mov D$hInstance eax               



مقدار برگشتی درون رجیستر eax  همان دستگیره ی پنجره (یعنی   hInstance)  می باشد .

تابع  RegisterClassExA  کلاس پنجره ی برنامه مان  را ثبت می کند . این تابع به ساختار  WNDCLASSEX  نیاز دارد طوریکه ما بتوانیم آنرا با مقادیر صحیح پر کنیم .  در اینجا بخشی از کد برنامه را  که به این ساختار نیاز دارد می نویسم

+

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

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

+

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

+

ادامه ی تدریس :

+

دستورات زیر به ساختار  WNDCLASSEX  مربوط می شوند :


    mov D$cbSize  030       ;size in bytes of WNDCLASSEX structure
    mov D$style  3           ;window style
    mov D$lpfnWndProc  WP1       ;address of user lpfnWndProc function
    mov D$cbclsExtra  0             ;extra bytes to allocate set to 0
    mov D$cbWndExtra  0                  ;class directive in rc file
    mov D$hbrBackground,2         ;background,1=background
    mov D$lpszMenuName   M00_Menu         ;menu ID in resource file
    mov D$lpszClassName   ClassName      ;name of windows class
    mov D$hIconSm   0              ;iconhandle 0=search in rc file


+

تابع  LoadIconA  یک آیکون تعریف شده در فایل ریسورس را تعریف می کند و  دستگیره را در ساختار  WNDCLASSEX  ذخیره می کند .


    push   1                   ;icon resource id
    push    D$hInstance            ;our program handle
    call    'USER32.LoadIconA'            ;- API Function -
    mov    D$hIcon    eax            ;handle of newly loaded icon


+

تابع  LoadCursorA  همانطور که از نامش پیداست یک کرسر پیشفرض سیستم را بارگیری می کند .

فقط بدانید که   ثابت  lpCursorName   معادل با عدد  دسیمال   32512 می باشد . بقیه ی توضیحات را  بخوانید.

;------------------------------------------------------------------------------
; API 'LoadCursorA' loads a default system cursor, in this case we must set
; hInstance to 0 and lpCursorName to a default system cursor value, here 32512
; Then we store the cursor handle in the 'WNDCLASSEX' structure
;------------------------------------------------------------------------------
    push    32512                         ;lpCursorName,default value in decimal
    push   0                                ;hInstance, 0=default system cursor
    call   'USER32.LoadCursorA'          ;- API Function -
    mov   D$hcursor   eax                  ;handle of the cursor

;------------------------------------------------------------------------------
; Now, after filled the 'WNDCLASSEX' structure we call API 'RegisterClassEx'
;------------------------------------------------------------------------------
    push   cbSize                        ;pointer to WNDCLASSEX structure
    call    'USER32.RegisterClassExA'     ;- API Function
-

;==============================================================================
; API 'CreateWindowExA' creates an overlapped, pop-up, or child window with an
; extended style. The return value in EAX is the handle of the new window.
;------------------------------------------------------------------------------
    push 0                             ;lpParam, extra pointer data 0=no data
    push D$hInstance                   ;hInstance, handle of our program
    push 0                             ;hMenu, handle window menu 0=class menu
    push 0                             ;hWndParent, handle parent window 0=no
    push 0F8                           ;intnHeight, window height pixel
    push 020A                          ;intnWidth, window width pixel
    push 0A0                           ;inty, vertical position window
    push 0B0                           ;intx, horizontal position window
    push 04CA0000                      ;dwStyle, 0=no sysmenu/close buttons
    push WindowName                    ;lpWindowName, pointer to window name
    push ClassName                     ;lpClassName, pointer to class name
    push 0300                          ;dwExStyle, extra window style 0=no
    call 'USER32.CreateWindowExA'      ;- API Function -
    mov D$hWnd,eax                     ;hwnd,return value=handle of window


تابع CreateWindowExA  تابع اصلی برای خلق و ایجاد پنجره در سیستم برنامه نویسی win32 در زبانهای اسمبلی و سی  می باشد  که شما  کاربرد این تابع را در بالا در زبان اسمبلی مشاهده می کنید .

;==============================================================================
; API 'ShowWindow' function sets the specified window's show state.
;------------------------------------------------------------------------------
    push   1                             ;nCmdShow, show state 1=SW_SHOWNORMAL
    push   D$hWnd                        ;hwnd, handle of window
    call   'USER32.ShowWindow'           ;- API Function -


در دستور  push 1   عدد 1 معادل با  SW_SHOWNORMAL می باشد یعنی اینکه پنجره ی اصلی برنامه به شکل استاندارد ویندوزی  نمایش داده می شود  . عملا می توان این پنحره را با استفاده از سایر اعداد  تغییر شکل داد و میزکار برنامه های ویندوزی را  سفارشی کرد .

عبارت SW_SHOWNORMAL    یک ثابت ویندوزی می باشد و  مقدارش همیشه برابر با عدد 1  است .

کلا روتین بالایی  در عمل ، پنجره ی اصلی برنامه ی ویندوزی را نمایش می دهد .

;==============================================================================
; API 'UpdateWindow' updates the area of the specified window by sending a
; WM_PAINT message to the window if the window's update region is not empty.
;------------------------------------------------------------------------------
    push D$hWnd                        ;hwnd, handle of window
    call 'USER32.UpdateWindow'         ;- API Function -


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

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

عبارت  WM_PAINT  یک پیام یا رویداد ویندوزی می باشد که کارش ترسیم کردن است .  زبان اسمبلی همه ی پیامهای ویندوزی را مستقیما بکار میگیرد درحالیکه بسیاری از زبانهای سطح بالا فقط تعداد اندکی از  پیامهای ویندوز را می شناسند و بکار می گیرند !!!

حالا کدوم قویتر و باهوشتره ؟؟  اسمبلی یا زبانهای سطح بالا ؟؟؟  خودتان قضاوت کنید .

+

حالا می رسیم به کدهای جدید که در این برنامه نوشته شده ولی در برنامه ی پنجره ی ساده ی ویندوزی نوشته نشده بودند. چون او یک پنجره ی ساده بود ولی این برنامه قرار است یک صدا تولید کند :

;==============================================================================
; API 'PlaySoundA' plays a wave sound, the value 40005h means the sound is
; inside the resource file.
;------------------------------------------------------------------------------
    push 040005                         ;SND_RESOURCE+SND_ASYNC
    push D$hInstance                    ;handle of our program
    push 1                              ;wave ID in rc file
    call 'WINMM.PlaySoundA'             ;- API Function -

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

  عدد  40005h  یک کد هگز زبان ماشین است که ثابت می کند صدا در درون فایل ریسورس قرار دارد .  در اسمبلر روسسم  اعداد هگز را با پیشوند 0 نمایش می دهند و بنابراین عدد 40005h در این اسمبلر بصورت 040005 نمایش داده می شود . عملا این سبک به دیس اسمبلی نزدیکتر است زیرا در دیس اسمبلی نیز این عدد دقیقا بصورت  040005  نمایش داده می شود .

;==============================================================================
; API 'GetMessageA' retrieves a message & places it in the specified structure.
;------------------------------------------------------------------------------
LoopGetMessage:
    push 0                             ;wMsgFilterMax, highest message value
    push 0                             ;wMsgFilterMin, lowest message value
    push 0                             ;hWnd, handle of window who gets msg.
    push hWnd                          ;lpMsg, pointer to MSG structure
    call 'USER32.GetMessageA'          ;- API Function -
    cmp eax 0                          ;check if return value=0 (exit)
    je ExitPrg                         ;if return value is 0 goto LABEL


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

دستور je   مخفف عبارت  jump if equal  می باشد . یعنی اگر دو عملوند با هم یکسان بودند به سمت فلان روتین پرش کن .  در اینجا مقدار برگشتی که در داخل رجیستر eax قرار دارد باید معادل با عدد صفر باشد . اگر صفر بود انوقت به روتین  Exitprg   پرش می کنیم .

;==============================================================================
; API 'TranslateMessage' translates key code into ASCII character messages
;------------------------------------------------------------------------------
    push hWnd                          ;lpMSG, pointer to msg structure
    call 'USER32.TranslateMessage'     ;- API Function - keyboard code



تابع  TranslateMessage همانطور که از نامش پیداست کد کلید را به پیامهای مربوط به  کارکتر  اسکی ترجمه می کند . شما حتما این تابع را در برنامه های زبان  برنامه نویسی  C  مشاهده کرده اید .

+

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

+

آیا می دانید چرا زبان C و فرزند شیئ گرای اش یعنی  ++C  (سی پلاس پلاس)    بعنوان قدرتمندترین  و محبوبترین زبانهای برنامه نویسی دنیا لقب گرفته اند ؟؟؟

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

+ انوفت برنامه نویسان زبانهای سطح بالا خیال می کنند که زبانهای خانواده ی  سی  از زبان اسمبلی قدرتمندتر و کاملتر هستند !!!!!!

+

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

+

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

امان از بیسوادی برنامه نویسان  زبانهای سطح بالا که ناخواسته زبان اسمبلی را تایید می کنند بدون انکه خودشان بفهمند !!!!

+

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

+

عملا هیج فرقی بین زبان اسمبلی و زبانهای خانواده ی C  وجود ندارد .  چون این زبانها همگی از روی زبان اسمبلی کپی برداری کرده اند .

+

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

+

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

+


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


;==============================================================================
; API 'DispatchMessageA' function dispatches a message to a window procedure.
;------------------------------------------------------------------------------
    push hWnd                          ;lpMSG, pointer to msg structure
    call 'USER32.DispatchMessageA'     ;- API Function -
    jmp LoopGetMessage                 ;check for message again, goto LABEL


برنامه نویسان زبانهای   C  و  ++C  خوب می دانند که این تابع و تابع قبلی در این دو زبان چقدر نقش مهم و کلیدی دارند . بازهم کپی برداری از روی زبان اسمبلی و بازهم نیرنگهای این دو زبان .

+

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

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

+

بیل گیتس  و استیو جابز  با کمک همین زبان  C   میلیاردها دلار  ثروت نامشروع  به جیب زدند و میلیاردها کاربر  را بدبخت و بیچاره کردند . خدا هردوشان را لعنت کند .  لعنت خدا  بر مایکروسافت و اپل و بنیانگذاران پول پرست و شیاد و دروغگوی این دو شرکت خبیث .

;==============================================================================
; Next we terminate our program (API=ExitProcess)


بعد ، ما  برنامه مان را  پایان می دهیم . البته با تابع  ExitProcess   . 


;------------------------------------------------------------------------------
ExitPrg:
    push D$hInstance                   ;push our programm handle to exit
    call 'KERNEL32.ExitProcess'        ;- API Function -


+

+

+

حالا ما  می رسیم به روال پنجره ی برنامه مان که قرار است  پیامهای ویندوز (رویدادها)  در ان  رد و بدل شوند :


;##############################################################################
; This is the Window Procedure lpfnWndProc (API=RegisterClassExA) for this
; registered window.
; The WindowProc function is an application-defined callback function that
; processes messages sent to a window.
; Here our code for checking the receiving messages resist.
; In the future it is the main work for us to react to the recieved messages.
; It is also a good idea to PUSHAD all register, because than we are free to
; use all register in this window procedure.
; Before we leave this subroutine we must POPAD them back.
;------------------------------------------------------------------------------
WP1:
    push ebp                           ;create stack frame
    mov ebp esp                        ;
    pushad                             ;push all register to the stack

    mov eax D$WP1_uMsg                 ;move the message number in eax
;==============================================================================
; WM_Destroy (value=02) message received ?
;------------------------------------------------------------------------------
WP1_uMsg_02h:
    cmp eax 2                          ;check if value=02 (WM_DESTROY)
    jne WP1_uMsg_0F                    ;if not 2h go to LABEL

;------------------------------------------------------------------------------
; API 'PostQuitMessage' indicates to Windows a request to terminate
;------------------------------------------------------------------------------
    push 0                             ;nExitCode, exit code=wParam
    call 'USER32.PostQuitMessage'      ;- API Function -
    popad                              ;pop all register back from stack
    xor eax eax                        ;set eax to 0 to exit our program
    mov esp ebp                        ;delete stack frame
    pop ebp                            ;
    ret 010                            ;return and clear stack

;==============================================================================
; WM_PAINT (value=0F) message, used to repaint the window area
;------------------------------------------------------------------------------
WP1_uMsg_0F:
    cmp eax,0F                         ;check if WM_PAINT message recieved
    jne WP1_uMsg_0111                   ;if not goto label
    jmp WP1_return

;==============================================================================
; WM_COMMAND (value=0111) message recieved ?
;------------------------------------------------------------------------------
WP1_uMsg_0111:                         ;WM_COMMAND message, value=111h
    cmp eax 0111                       ;check if WM_COMMAND message recieved
    jne WP1_return                     ;if not goto label

;------------------------------------------------------------------------------
; Check for extra message information, '&Exit' item in menu bar
;------------------------------------------------------------------------------
WP1_wParam_01:
    mov eax D$WP1_wParam               ;extra info about the message
    cmp ax 1001                        ;ID of '&Exit' item in Menu
    jne WP1_return                     ;if not 01001 goto LABEL

;------------------------------------------------------------------------------
; API 'MessageBoxA' creates a message box, we can choose if we want exit prg.
;------------------------------------------------------------------------------
    push 04                            ;uType, style, 4=MB_YESNO Button
    push MB1Titel                      ;lpCaption,pointer to title text
    push MB1Text                       ;lpText,pointer to text message box
    push D$WP1_hWnd                    ;handle of owner window 0=no owner
    call 'USER32.MessageBoxA'          ;- API Function -
    cmp eax 06                         ;if return value=6h (IDYES) then exit
    jne WP1_return                     ;if return value=7h (IDNO) goto LABEL

;------------------------------------------------------------------------------
; API 'DestroyWindow' function destroys the given window
;------------------------------------------------------------------------------
    push D$WP1_hWnd                    ;hwnd, handle of window to destroy
    call 'USER32.DestroyWindow'        ;- API Function -
    jmp WP1_return

;==============================================================================
; API 'DefWindowProcA' calls the window procedure to provide default processing
; for any window messages that an application does not process.
; This function ensures that every message is processed.
; It is called with the same parameters received by the window procedure.
;------------------------------------------------------------------------------
WP1_return:
    popad                              ;pop all register from stack
    push D$WP1_lParam                  ;extra info about the message
    push D$WP1_wParam                  ;extra info about the message
    push D$WP1_uMsg                    ;the message number
    push D$WP1_hWnd                    ;handle of window who receives message
    call 'USER32.DefWindowProcA'       ;- API Function -
    mov esp ebp                        ;delete stack frame
    pop ebp                            ;
    ret 010                            ;return and clear stack

;##############################################################################



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

+

 ببخشید ولی  واقعا اسمبلی زبان هرکسی نیست .   طرفداران زبان  C    می گویند که  سی  زبان بچه ها نیست .  من با عرض معذرت از همه ی کاربران کامپیوتر در سرتاسر دنیا  عرض می کنم که اسمبلی زبان هیچکس نیست مگر دیوانه هایی مثل خودم !!!!!

+

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

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

+

بدبختانه چون بیش از 90 درصد برنامه نویسان دنیا از زبان اسمبلی متنفرند  لذا هیچوقت انرا بدرستی درک نمی کنند و همیشه از مزایای این زبان محرومند .


+

+

+

 با توجه به پیچیده بودن  برنامه های آموزشی  سری  TDtuts   ،  ترجیح می دهم که از سری آموزشی استاندارد و ساده و قابل فهم   ایکزیلیون  برای تدریس زبان اسمبلی استفاده کنم .

+


برنامه های آموزشی ایکزیلیون  (Iczelion)  عملا ساده تر و کوچکتر و قابل فهمتر و استاندادتر هستند و برای اکثر اسمبلرها  نوشته شده اند .

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

==

==

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

+

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

+

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

+

بابت  اپدیت دیر به دیر  وبلاگ عذرخواهی می کنم . چون کار بسیار سختی را باید به تنهایی انجام دهم که خب طبیعتا   بسیار وقتگیر است .

+

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


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

+

پس لطفا  صبور باشید  تا  کم کم  تمامی اجزای پکیج اسمبلر  روسسم را  بازنویسی کنم   و مجددا  آپلود کنم .

+

علی الحساب  به محض انکه برنامه های اموزشی  ایکزیلیون  اماده شدند انها را با سورس جدید و اصلاح شده ،  اینجا  اپلود  کرده و سپس توی همبن وبلاگ  آنها را  آموزش می دهم . انشاء ا.....

+

تا بعد .  

+

محبوبه  زرین -   شهریور  1397   هجری شمسی . 





موافقین ۱ مخالفین ۰ ۱۹ شهریور ۹۷ ، ۰۰:۰۰
محبوبه زرین