ايران ويج

نسخه‌ی کامل: یه سوال در مورد اسمبلی
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
صفحه‌ها: 1 2
سلام به شما دوستان عزیز .
امیدوارم حال همگی خوب باشه .
ببخشید این سوال رو اینجا می پرسم ولی دیگه جایی بهتر از اینجا به ذهنم نرسید .
سوال من در مورد اسمبلی هست .
ظاهرا در این انجمن درباره ی زبان اسمبلی بحث نمیشه .
و اما سوال :
آیا میشه با استفاده از دستورات اسمبلی یه برنامه نوشت که گرافیک داشته باشه ؟!
مثلا مثل برنامه ای باشه که با فکس پرو نوشته شده ...
من هر برنامه ای دیدم که به زبان اسمبلی نوشته شده همش تحت داسه و نه شکلی داره و نه قیافه ای !
شما باید از API ها استفاده کنید
یادم میاد تو یه جا که آموزش اسمیال داده بود طرز استفاده از
تابع messagebox رو توظیح داده بود
شما هم اگه میخای با اسمبلی از GUI استفاده کنی باید از API های
مخصوص ایجاد پنجره استفاده کنید که البته خییییییییییییلی سخته
با C و VB خیلی راحتتره
همین طور که دوستمون arian_vc گفتند با اسمبلی میشه واسه ویندوز هر برنامه ای نوشت ولی کار با API ها در سطح پایین و ذخیره و بازیابی اطلاعات اونها ( در مورد پارامتر ها و مقدار های بازگشتی ) خیلی خیلی مشکل و وقت گیره و ترجیحا مورد توجه برنامه نویسان نیست . تمام برنامه هایی که توی ویندوز میبینید میتونن با زبان اسمبلی هم نوشته بشن ولی ممکنه ساخت بعضی از اونها چندین سال طول بکشه !! همچنین اینقدر برنامه به اصطلاح Bug prone یا پر خطا خواهد بود که حتی Debugging اون هم از حوصله خارجه .
سلام ...
ممنون از توضیحات شما دوستان خوبم ...
پس با این اوصاف برنامه نویسی به زبان اسمبلی چه فایده ای داره ؟!!
نقل قول: پس با این اوصاف برنامه نویسی به زبان اسمبلی چه فایده ای داره ؟!!

خوب کاربرد های خودش رو داره . برنامه هایی که با مباحث سطح پایین کار دارن مثل درایور ها یا برنامه هایی که سخت افزار های مختلف یا وسایل الکترونیکی متصل به PC رو کنترل می کنند و یا برنامه هایی که نیاز دارند از ویژگی های خاص CPU مثل دسترسی به دستور العمل های MMX یا XMM و رجیستر های مربوط به اونها دست پیدا کنند مثال : کتابخونه های صوتی و تصویری که از نمونه های اون میتونیم همین DirectX یا OpenGL رو مثال بزنیم و ..... خیلی چیزهای دیگه . Question
فقط این نکته رو بگم در موارد خاص از زبانهای سطح پایین استفاده میشه نه همیشه . امروزه برای ساخت برنامه های تجاری یا همون Application ها به ندرت از زبان اسمبلی اسفتاده میشه و معمولا کارهای سطح پایین با کمک کتابخونه های آماده حل میشن . حالا ممکنه یکی بخواد این کد نویسی های سطح پایین رو خودش انجام بده که اونوقت نیاز هست که از اسمبلی هم استفاده بکنه .
در بیشتر مواقع ، تیم های نرم افزاری که کمتر کاری با سخت افزار یا سطح پایین دارند سعی می کنند نیاز های اندک خودشون رو با همون کتابخونه ها و کد های آماده بر طرف کنند و از اتلاف وقت بیهوده و درگیری با زبان اسمبلی دوری می کننShy
اسم API هم createwindow یا create windowex
که دومی پیشرفته تر از اولیه : باهاش میشه پنجره و کنترل درست کرد
آقا خیلی خیلی خیلی ممنون ، واقعا از مطالب مفید هر دوی شما استفاده می کنم .
این توابع رو باید از کجا یاد گرفت ؟
شیوه ی پیاده کردن این توابع در زبان اسمبلی به چه شکله ؟
فراگیری زبان اسمبلی در کرک نرم افزار چقدر می تونه نقش داشته باشه ؟
ممنون ...
نقل قول: اسم API هم createwindow یا create windowex
که دومی پیشرفته تر از اولیه : باهاش میشه پنجره و کنترل درست کرد

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

نقل قول: این توابع رو باید از کجا یاد گرفت ؟

این توابع همون توابع API هستند Smile

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

یه وب سایت بهت میدم برو . همه چیز درباره برنامه نویسی ویندوز با اسمبلی : http://win32asm.cjb.net/

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

شما تا اسمبلی رو بلد نباشی نمیتونی کدهای برنامه اسمبل شده ( فایل EXE ) رو بخونی و در واقع یعنی بدون اسمبلی ، کرک کردن امکان نداره !
اسم اون استراکچر هم wndclass هست
بعدش با تابع registerclassex رجیستر میشه
من فقط خواستم کوتاهتر جواب بدم
به نام خدا

این بحثو بی خیالشید اما چرا؟؟؟ Amaze
این جا یک برنامهء خیلی کوچیک Windows را با Assembly آوردم
یک نگاه بنداز همه چی دستت می آد!!! Question

این که می گند assembly زبانه توپیه واسه اینه که توابع بحرانی برنامه را با اون
بنویسی نه این که کله برنامه رو Laugh ، اگه بخوای این کارو بکنی میشه این:

کد:
.model  small, pascal, nearstack
                .286

                ?WINPROLOGUE = 1
                NOKERNEL = 1
                NOSOUND = 1
                NOCOMM = 1
                NODRIVERS = 1
                include win.inc                 ; Converted from WINDOWS.H

;----------------------------------------------------------------------------;
;                        Prototypes & External Definitions                   ;
;----------------------------------------------------------------------------;

WinMain          PROTO PASCAL, hInstance:HANDLE,  hPrevInstance:HANDLE,
                        lpszCmdLine:LPSTR, nCmdShow:SWORD
WndProc          PROTO FAR PASCAL,  :HWND, :WORD, :SWORD, :SDWORD
Initialize       PROTO,             :PINT, :PINT, :PINT,  :PINT
Resize           PROTO,             :HWND
SetupTimer       PROTO,             :HWND, :WORD

extern __astart:proc            ; When Windows load an app, it expects astart
                                ; to have the necessary start-up code. We get
                                ; astart from APPENTRY.ASM

;----------------------------------------------------------------------------;
;                             Numeric Equates                                ;
;----------------------------------------------------------------------------;

INIT_FONT        EQU    30t             ; initial font height
MAX_HEIGHT       EQU    100             ; Maximum Font Height
TOP_CORNER       EQU    1               ; Set to 0 for Lower-Right Corner Clock

IDM_DATE         EQU    1t              ; definitions for Menu items
IDM_ALARM        EQU    2t
IDM_SET          EQU    3t
IDM_MENU         EQU    4t
IDM_EXIT         EQU    5t
IDM_ABOUT        EQU    6t
IDM_MINIMIZE     EQU    7t
IDM_ONTOP        EQU    8t
AMPM             EQU    3t              ; length of am/pm strings
SCROLLCHILD      EQU    30t             ; identifies scroll: any number will do
MAXTIME          EQU    1439t           ; max # of minutes
TIMER_SECS       EQU    1000t           ; timer interval: 1000 mill = 1 second
TIMER_MINS       EQU    60000t          ; interval for 1 minute: 1000 * 60
ICON_LEN         EQU    7t              ; # of chars to display icon time

;----------------------------------------------------------------------------;
;                               Data Segments                                ;
;----------------------------------------------------------------------------;

                .const          

szAppName       SBYTE   "WINClock",0                  

DateFmt         SBYTE   " %s %2d, %04d ",13,10,0
TimeFmt         SBYTE   " %d:%02d:%02d %s ",0
IconFmt         SBYTE   " %d:%02d ",0
AlarmFmt        SBYTE   " %d:%02d %s ",0
szAMPM          SBYTE   "am",0,"pm",0                  
szTooManyTimers SBYTE   "Too many clocks or timers!",0
szAlarmMsg      SBYTE   "Remember your Appointment!",0
szMonths        SBYTE   "Jan",0,"Feb",0,"Mar",0,"Apr",0,"May",0,"Jun",0,
                        "Jul",0,"Aug",0,"Sep",0,"Oct",0,"Nov",0,"Dec",0
szDateCmd       SBYTE   "Enable &Date", 0
szSetCmd        SBYTE   "S&et Alarm",0
szAlarmCmd      SBYTE   "Enable &Alarm", 0
szOnTopCmd      SBYTE   "Always on &Top",0
szMinimizeCmd   SBYTE   "&Minimize", 0
szExitCmd       SBYTE   "E&xit", 0
szAboutCmd      SBYTE   "About &Clock...", 0
szAboutText     SBYTE   "Assembler Program Using the Windows API", 0
szDisplay       SBYTE   "DISPLAY", 0    ; to get a handle to entire display
szScrollBar     SBYTE   "scrollbar", 0  ; to create scrollbar 'class'                

                .data

EnableDate      BYTE    MF_CHECKED      ; Date initially enabled
EnableAlarm     BYTE    MF_UNCHECKED    ; Alarm initially disabled
AlwaysOnTop     BYTE    MF_CHECKED      ; Window will be on topmost
Iconized        BYTE    FALSE           ; Clock initially Normal Size
TestAlarm       BYTE    FALSE           ; so that we know to test for the alarm
SetAlarm        BYTE    FALSE           ; signalling while we set the alarm
AlarmTime       WORD    (MAXTIME/2)+1   ; initial alarm time: 12:00 pm

                .data?

cBuffer         SBYTE   40 dup (?)      ; buffer to receive text for drawing
hMenu           HMENU   ?               ; handle to Popup Menu
logfont         LOGFONT { }             ; logical font structure
hWndScrol       HWND    ?               ; handle to the scroll window
TextRect        RECT    { }             ; rectangle to draw text in

;----------------------------------------------------------------------------;
;                               Code Segment                                 ;
;----------------------------------------------------------------------------;

                .code

;----------------------------------------------------------------------------;
;                               WinMain                                      ;
;----------------------------------------------------------------------------;
;                                                                            ;
; Main routine called by Windows in program start. If no previous instances, ;
; sets up a window class and registers it. Initializes the program with      ;
; Initialize, creates a top window with the coordinates from Initialize, sets;
; up a child scroll bar control, and sets up the message loop.               ;
;                                                                            ;
;----------------------------------------------------------------------------;

WinMain         PROC,   hInstance:HANDLE,  hPrevInstance:HANDLE,
                        lpszCmdLine:LPSTR, nCmdShow:SWORD
                LOCAL   msg:MSG, wndclass:WNDCLASS, xStart:SWORD,
                        yStart:SWORD, xClient:SWORD, yClient:SWORD

                ; Local variables: msg: message to be used in the message loop
                ;                  wndclass: temp. to store window class
                ;                  x,y Start-Client: Size of Initial Window
;
;--- Check for previous instances
;
                .IF (hPrevInstance == 0)

                        lea     di, wndclass    ; because we use a NEARSTACK,
                        ASSUME  di:PTR WNDCLASS ; ss=ds

                        mov     ax, CS_HREDRAW OR CS_VREDRAW OR CS_DBLCLKS
                        mov     [di].style, ax
                        mov     WORD PTR [di].lpfnWndProc,   LROFFSET WndProc
                        mov     WORD PTR [di].lpfnWndProc+2, SEG WndProc
                        xor     ax,ax
                        mov     [di].cbClsExtra, ax
                        mov     [di].cbWndExtra, ax

                        mov     [di].hIcon, ax  ; null icon: we will draw it

                        mov     ax, hInstance
                        mov     [di].hInstance, ax

                        INVOKE  LoadCursor, NULL, IDC_ARROW
                        mov     [di].hCursor, ax

                        INVOKE  GetStockObject, WHITE_BRUSH
                        mov     [di].hbrBackground, ax

                        xor     ax, ax
                        mov     WORD PTR [di].lpszMenuName,   ax
                        mov     WORD PTR [di].lpszMenuName+2, ax

                        mov     WORD PTR [di].lpszClassName,   OFFSET szAppName
                        mov     WORD PTR [di].lpszClassName+2, ds

                        INVOKE  RegisterClass, di
                        .IF (ax == 0)
                                mov     ax, FALSE
                                jmp     doRet
                        .ENDIF

                        ASSUME  di:NOTHING        

                .ENDIF     ;--- End of IF (hPrevInstance == 0)

;
;---- Initialize
;

                INVOKE  Initialize, ADDR xStart,  ADDR yStart,
                                    ADDR xClient, ADDR yClient

;
;---- Create Top Window
;

                INVOKE  CreateWindowEx, WS_EX_TOPMOST, ADDR szAppName,
                        ADDR szAppName, WS_BORDER OR WS_POPUP OR WS_THICKFRAME,
                        xStart, yStart, xClient, yClient, NULL, NULL,
                        hInstance, NULL
                mov     si, ax          ; keep hWnd in SI, since SI doesn't
                                        ; change after function calls

                INVOKE  ShowWindow,    si, SW_SHOWNOACTIVATE
                INVOKE  UpdateWindow,  si
                                
                
;
;----Create Scroll Child Window
;

                INVOKE  CreateWindow, ADDR szScrollBar, NULL,
                        WS_CHILD OR WS_VISIBLE OR WS_TABSTOP OR SBS_HORZ,
                        0, 0, 0, 0, si, SCROLLCHILD, hInstance, NULL
                mov     hWndScrol, ax

                INVOKE  SetScrollRange, ax, SB_CTL, 0, MAXTIME, FALSE
                INVOKE  SetScrollPos,   hWndScrol, SB_CTL, AlarmTime, FALSE

                INVOKE  ShowScrollBar,  hWndScrol, SB_CTL, TRUE
                INVOKE  ShowWindow,    hWndScrol, SW_SHOWNOACTIVATE
                INVOKE  UpdateWindow,  hWndScrol

;
;---- Message Loop
;

                .WHILE TRUE

                        INVOKE  GetMessage,    ADDR msg, NULL, 0, 0

                        .BREAK .IF (ax == 0)

                        INVOKE  TranslateMessage, ADDR msg
                        INVOKE  DispatchMessage,  ADDR msg

                .ENDW

;
;---- Return to Windows
;

                mov     ax, msg.wParam
doRet:
                ret

WinMain         ENDP


;----------------------------------------------------------------------------;
;                                Initialize                                  ;
;----------------------------------------------------------------------------;
;                                                                            ;
; Initializes the logfont struct, sizes the Initial Window, Makes the Menu.  ;  
;                                                                            ;
; For the size of the initial window: We get the DC for the entire display,  ;
; and calculate the size of the font into tmetric. With that, we allow for   ;
; the necessary distance from the top right corner so that there's enough    ;
; space for the text.                                                        ;
;                                                                            ;
;----------------------------------------------------------------------------;

Initialize      PROC USES si di, pxStart:PINT, pyStart:PINT,
                                 pxClient:PINT, pyClient:PINT
                ; px,py,Start,Client will hold the dimensions of the initial
                ; window to create

                LOCAL hFont:HFONT, hDC:HDC, tmetric:TEXTMETRIC
                ; locals: a handle to a font, one to a device context,
                ;         and a textmetric structure

;
;---- Initialize the logfont structure
;
        
                mov     bx, OFFSET logfont

                ASSUME  bx:PTR LOGFONT

                xor     ax, ax
                mov     [bx].lfHeight, INIT_FONT; Initial Font Height
                mov     [bx].lfWidth,  ax       ; width's set according to hght
                mov     [bx].lfEscapement, ax
                mov     [bx].lfOrientation, ax
                mov     [bx].lfWeight, FW_NORMAL
                mov     [bx].lfItalic, al
                mov     [bx].lfUnderline, al
                mov     [bx].lfStrikeOut, al
                mov     [bx].lfCharSet, ANSI_CHARSET
                mov     [bx].lfOutPrecision, al
                mov     [bx].lfClipPrecision, al
                mov     [bx].lfQuality, al
                mov     [bx].lfPitchAndFamily, DEFAULT_PITCH OR FF_SWISS
                mov     [bx].lfFaceName, NULL

                ASSUME  bx:NOTHING

;---- Get Initial Size for the Window Based on Font

                xor     dx, dx
                INVOKE  CreateIC, ADDR szDisplay, dx::dx, dx::dx, dx::dx
                mov     hDC, ax

                INVOKE  CreateFontIndirect, ADDR logfont
                mov     hFont, ax

                INVOKE  SelectObject, hDC, ax
                mov     hFont, ax

                INVOKE  GetTextMetrics, hDC, ADDR tmetric

                INVOKE  SelectObject, hDC, hFont

                INVOKE  DeleteObject, ax

                INVOKE  DeleteDC, hDC

                INVOKE  GetSystemMetrics, SM_CXDLGFRAME ; Set window width
                shl     ax, 1                           ; frame*2      
                mov     bx, tmetric.tmAveCharWidth      ; width of font
                mov     cl, 4                           ; to shift
                shl     bx, cl                          ; width*16
                add     ax, bx                          ; frame*2 + width*16
                mov     si, pxClient                    ; address to store in
                mov     [si], ax                        ; store

                INVOKE  GetSystemMetrics, SM_CXSCREEN   ; screen x-length
                mov     si, pxClient                    ; window width
                sub     ax, [si]                        ; start=corner-winWdth
                mov     si, pxStart                     ; store result
                mov     [si], ax

                INVOKE  GetSystemMetrics, SM_CYDLGFRAME ; Set Height
                shl     ax, 1                           ; frame*2
                mov     bx, tmetric.tmHeight            ; height*2
                shl     bx, 1
                add     ax, bx                          ; add
                mov     si, pyClient                    ; store in pyClient
                mov     [si], ax

                IF TOP_CORNER                           ; if Top Corner,
                        xor     ax, ax                  ; yStart=0
                ELSE                                    ; else,
                        INVOKE  GetSystemMetrics, SM_CYSCREEN  
                        mov     si, pyClient            ; yStart = ScreenHgth
                        sub     ax, [si]                ; minus yHeight
                ENDIF
                mov     si, pyStart                     ; set yStart
                mov     [si], ax


;
;---- Initialize the Menu
;

                INVOKE CreatePopupMenu
                mov hMenu, ax
                                                ; Date is Initially Enabled
                INVOKE  AppendMenu, hMenu, MF_STRING OR MF_CHECKED, IDM_DATE,
                                    ADDR szDateCmd
                INVOKE  AppendMenu, hMenu, MF_STRING, IDM_ALARM,ADDR szAlarmCmd
                INVOKE  AppendMenu, hMenu, MF_STRING, IDM_SET, ADDR szSetCmd
                INVOKE  AppendMenu, hMenu, MF_SEPARATOR, 0, NULL
                INVOKE  AppendMenu, hMenu, MF_STRING OR MF_CHECKED, IDM_ONTOP,
                                    ADDR szOnTopCmd
                INVOKE  AppendMenu, hMenu, MF_STRING, IDM_MINIMIZE,
                                    ADDR szMinimizeCmd
                INVOKE  AppendMenu, hMenu, MF_STRING, IDM_EXIT, ADDR szExitCmd
                INVOKE  AppendMenu, hMenu, MF_SEPARATOR, 0, NULL
                INVOKE  AppendMenu, hMenu, MF_STRING, IDM_ABOUT,ADDR szAboutCmd
                ret

Initialize      ENDP

;----------------------------------------------------------------------------;
;                                SetupTimer                                  ;
;----------------------------------------------------------------------------;
;                                                                            ;
; Setup a timer with the specified interval. If we can't set up the timer,   ;
; output a message box and exit the program.                                 ;
;----------------------------------------------------------------------------;

SetupTimer PROC NEAR, hWnd:HWND, Interval:WORD
                ; hWnd is the Handle of the Window to associate the timer with
                ; Interval is the interval in milliseconds

                INVOKE  SetTimer, hWnd, 1, Interval, NULL
                .IF (ax == 0)
                        INVOKE  MessageBox, hWnd,ADDR szTooManyTimers,
                                            ADDR szAppName,
                                            MB_ICONEXCLAMATION OR MB_OK
                        mov     ax, FALSE
                        INVOKE PostQuitMessage, 0               ; Quit.
                .ENDIF

                ret
SetupTimer ENDP

;----------------------------------------------------------------------------;
;                                AlarmSetup                                  ;
;----------------------------------------------------------------------------;
;                                                                            ;
; If we're going to set the alarm, kill the timer, show the scroll bar, and  ;
; resize the fonts. Enable the Alarm after it has been re-set.               ;
;                                                                            ;
; If we just set up the alarm, get a new timer,                              ;
; check the menu to enable the alarm, hide the scrollbar, resize the fonts   ;
; When creating the top window this is called to set up the initial timer.   ;
;                                                                            ;
;----------------------------------------------------------------------------;

AlarmSetup      PROC,   hWnd:HWND
                ; hWnd is the handle of the window that received WinPaint


                .IF SetAlarm
                        INVOKE  KillTimer, hWnd, 1
                        INVOKE  Resize, hWnd
                        INVOKE  ShowScrollBar, hWndScrol, SB_CTL, TRUE
                        INVOKE  SetFocus, hWndScrol
                        INVOKE  InvalidateRect, hWnd, NULL, TRUE
                        mov     EnableAlarm, MF_CHECKED
                        mov     TestAlarm, TRUE        

                .ELSE

                        INVOKE  SetupTimer, hWnd, TIMER_SECS
                        INVOKE  CheckMenuItem, hMenu, IDM_ALARM, EnableAlarm
                        INVOKE  ShowScrollBar,  hWndScrol, SB_CTL, FALSE
                        INVOKE  Resize,         hWnd
                        INVOKE  InvalidateRect, hWnd, NULL, TRUE

                .ENDIF          

                ret

AlarmSetup      ENDP
                
        
;----------------------------------------------------------------------------;
;                                    Resize                                  ;
;----------------------------------------------------------------------------;
;                                                                            ;
; Simple resizing, without taking into account aspect ratio.                 ;
; If we're setting the alarm, the scroll bar height will be (client hgt)/16, ;
; the length will be (client lenght)-(2*Scroll Bar Height), and the top will ;
; will start (in Client coordinates), at one SB Height right and 2 SBHeights ;
; up from the left bottom corner. Fonts width will be length/10, height will ;
; be (client height)-(3*Scroll bar height). The Scroll bar is also displayed.;
;                                                                            ;
; If we're not setting the alarm, and we're not minimized, font width will be;
; length/TIME_LEN and height will be either client height or client height/2,;
; depending on the date being enabled or not.                                ;
;                                                                            ;
; If font height is more than MAX_HEIGHT, then height is MAX_HEIGHT, and the ;
; TextRect.top is computed so that Drawing the text on the client area will  ;
; be centered.                                                               ;
;                                                                            ;
; If we're minimized, width=length/ICON_LEN, height is client height.        ;
;                                                                            ;
; The TextRect is used so that it's not recomputed everytime the Window is   ;
; repainted.                                                                 ;
;                                                                            ;
;----------------------------------------------------------------------------;

Resize          PROC,   hWnd:HWND
                ; hWnd is the handle of the window that received WinPaint
                LOCAL   rect:RECT
                ; holds a rectangle structure

                INVOKE  SetFocus, hWnd  ; take focus out of child window

                INVOKE  GetClientRect, hWnd, ADDR rect ; get new rect.size
                

;---- Find desired Text Height

                .IF SetAlarm    

;---- Calculate New TextRect allowing for Scroll Bar

                        mov     bx, rect.bottom   ; SXstart is length / 8
                        shr     bx, 3
                
                        mov     cx, rect.right    ; SLength=CLenght-2*SHeight
                        sub     cx, bx
                        sub     cx, bx

                        mov     dx, rect.bottom   ; SYstart will be CHgt-2*SHgt
                        sub     dx, bx
                        sub     dx, bx

                        mov     TextRect.bottom, dx  ; bottom = CHgt - 3*SHgt
                        sub     TextRect.bottom, bx

                        INVOKE  MoveWindow, hWndScrol, bx, dx, cx, bx, FALSE
                        INVOKE  SetScrollPos,hWndScrol,SB_CTL,AlarmTime,TRUE

                        mov     ax,TextRect.bottom   ; Try to use Full Height
                                                     ; for font height

;---- Else (not setting the alarm)

                .ELSE

                        mov     ax, rect.bottom      ; Full or Half Height
                        mov     TextRect.bottom, ax
                        .IF EnableDate && !Iconized
                                shr     ax, 1        ; height/2
                        .ENDIF
                .ENDIF          


;---- Test if desired height is allowed or not
;---- If height>MAX, then height=MAX_HEIGHT. Adjust TextRect.top by
;---- substracting from the bottom the font height (or twice that if Date),
;---- dividing by two, and adding to the TextRect.top.

                .IF (ax > MAX_HEIGHT)  
                        mov     logfont.lfHeight, MAX_HEIGHT
                        mov     ax, TextRect.bottom
                        mov     bx, MAX_HEIGHT
                        .IF EnableDate && !Iconized
                                shl     bx, 1
                        .ENDIF
                        sub     ax, bx
                        shr     ax, 1
                        mov     TextRect.top, ax
                .ELSE
                        mov     logfont.lfHeight, ax
                        mov     TextRect.top, 0

                .ENDIF

                mov     TextRect.left, 0                ; Left is Zero
                mov     ax, rect.right                  ; Same Rect length
                mov     TextRect.right, ax

;---- Set font width according to Iconized or not.

                .IF Iconized    
                        xor     dx, dx
                        mov     bx, ICON_LEN
                        div     bx
                .ELSE
                        shr     ax, 4        ; length/16
                .ENDIF
                mov     logfont.lfWidth, ax

                ret

Resize          ENDP
                
;----------------------------------------------------------------------------;
;                                  PaintAlarm                                ;
;----------------------------------------------------------------------------;
;                                                                            ;
; Painting the alarmtime. Get the hours and minutes from Alarmtime, get AM   ;
; or PM by going into szAMPM either at 0 or 3, to get the appropiate string. ;
; Then we simply draw the text into the TextRect calculated by Resize, with  ;
; the font that we get from using the logfont structure.                     ;
;                                                                            ;
;----------------------------------------------------------------------------;

PaintAlarm      PROC USES si di,  hWnd:HWND, hDC:HDC
                ; hWnd is the handle of the window that received WinPaint
                ; hDC is the Device context of the window

                LOCAL   nLength:SWORD, hFont:HFONT,
                        hour:WORD, minutes:WORD, seconds:WORD
                ; Locals: nLength is the current length of the buffer
                ;         hFont is a handle to a font.  

;---- Get Time from AlarmTime

                xor     dx, dx
                mov     ax, AlarmTime
                mov     bx, 60t
                div     bx                      ; ax holds the hours
                mov     bx, dx                  ; bx holds the minutes

                mov     si, ax                  ; si holds the hours
                xor     dx, dx
                mov     di, 12
                div     di                      ; will have ax=0 or 1 (am/pm)
                xor     dx, dx
                mov     cx, AMPM                ; AMPM = 3: 'am'+\0
                mul     cx
                mov     di, ax
                add     di,offset szAMPM        ; get into di the correct
                                                ; memory address        

                mov     ax, si                  ; ax == tm_hour
                xor     dx, dx
                mov     cx, 12
                div     cx
                .IF (dx == 0)                   ; so we don't have 00:45
                        mov cx, 12
                .ELSE
                        mov cx, dx
                .ENDIF
                
;---- on using wsprintf below: since the wsprintf prototype has VARARG,
;---- we can't tell the assemble the distance of those arguments, so we
;---- have to do a specific far pointer to the data. wsprintf expects all
;---- pointers to be far pointers, no exceptions.

                INVOKE  wsprintf, ADDR cBuffer, ADDR AlarmFmt,
                                  cx, bx, ds::di
                mov     nLength,ax

;---- Set Font & Draw Text

                INVOKE  CreateFontIndirect, ADDR logfont
                mov     hFont, ax
                INVOKE  SelectObject, hDC, ax
                mov     hFont, ax
                INVOKE  DrawText, hDC, ADDR cBuffer, nLength, ADDR TextRect,
                                       (DT_CENTER)
                INVOKE  SelectObject, hDC, hFont
                INVOKE  DeleteObject, ax

                ret

PaintAlarm      ENDP

;----------------------------------------------------------------------------;
;                                  PaintTime                                 ;
;----------------------------------------------------------------------------;
;                                                                            ;
; Painting the time. We get a index to szMonths by multiplying the [0-11]    ;
; month by 4 ('jan'+\0). We print everything to a string and store the length;
; as an index. We do this only if Date's enabled.                            ;
; For the time, we do the same AM/PM thing as in PaintAlarm, and print it to ;
; the same string after the Date's carriage return (included in DateFmt.     ;
; Then we simply draw the text into the TextRect calculated by Resize, with  ;
; the font that we get from using the logfont structure.                     ;
; If we're minimized, we also draw a rectangle around the time. We get a pen ;
; of width 2, black, and a hollow (transparent) brush. We save the pen ID in ;
; the stack so that we can deselect it later.                                ;
; Then, we check to see if we have to spring the alarm. If TestAlarm is not  ;
; enabled, check the time and re-enable TestAlarm if it's NOT the AlarmTime  ;
; (i.e. so that after we ring it it will ring in 24 hours). If TestAlarm is  ;
; set, check if EnableAlarm is set. If it is, multiply the hours by 60, add  ;
; the minutes, compare with AlarmTime. Notice that the 'mov bx, datetime' is ;
; necessary because the wsprintf and DrawText will trash ax, bx, cx. If it's ;
; alarm time, disable TestAlarm, invert the rectangle, sound a beep, revert  ;
; the rect, and do a message box. This way, TestAlarm enables us to always   ;
; have at least one check of the alarm time.                                 ;
;                                                                            ;
;----------------------------------------------------------------------------;

PaintTime       PROC USES si di,  hWnd:HWND, hDC:HDC
                ; hWnd is the handle of the window that received WinPaint
                ; hDC is the Device context of the window

                LOCAL   nLength:SWORD, hFont:HFONT, pen:WORD,
                        hour:WORD, minutes:WORD, seconds:WORD
                ; Locals: nLength is the current length of the buffer
                ;         hFont is a handle to a font.  

;---- Set Date Variables

                .IF (EnableDate && !Iconized)

                       mov     ah, 2Ah               ; function: Get Date
                       INVOKE  DOS3Call              ; do the interrupt
                                                     ; dh will have months
                                                     ; dl will have days
                                                     ; cx will have years

                        mov     al, dh               ; months (1-12)
                        xor     ah, ah
                        xor     dh, dh               ; day-of-month (1-31)
                

                        mov     si, ax               ; (Month-1) * 4
                        dec     si
                        shl     si, 2
                        add     si, offset szMonths

;---- For note on wsprintf below, see PaintAlarm

                        INVOKE  wsprintf, ADDR cBuffer, ADDR DateFmt,
                                  ds::si, dx, cx
                        mov nLength, ax
                .ELSE
                        mov nLength, 0

                .ENDIF ; of EnableDate

;---- Get Time from CPU clock
                xor     dx, dx

                mov     ah, 2Ch                      ; function: Get Time
                INVOKE  DOS3Call                     ; do the interrupt
                                                     ; ch will have hours
                                                     ; cl will have minutes
                                                     ; dh will have seconds

                mov     al, ch                       ; hours (0-23)
                xor     ah, ah
                mov     hour, ax        
                mov     al, cl                       ; minutes (0-59)
                mov     minutes, ax          
                mov     al, dh                       ; seconds (0-59)
                mov     seconds, ax          
  
                mov     ax, hour                     ; divide hour/12, multiply
                xor     dx, dx                       ; by 3 to get offset into
                mov     bx, 12                       ; szAMPM, then add the
                div     bx                           ; szAMPM offset
                mov     si, dx                       ; dx would have hours
                xor     dx, dx
                mov     cx, AMPM
                mul     cx
                mov     bx, ax
                add     bx, offset szAMPM            ; get into di the correct
                                                     ; memory address
                
                .IF (si == 0)                        ; get hour into cx
                        mov  cx, 12                  ; or 12 if hour=0
                .ELSE
                        mov  cx, si
                .ENDIF
                
                mov     si, nLength
                .IF !Iconized
                        INVOKE  wsprintf, ADDR cBuffer[si], ADDR TimeFmt,
                                          cx, minutes, seconds, ds::bx
                .ELSE
                        INVOKE  wsprintf, ADDR cBuffer[si], ADDR IconFmt,
                                          cx, minutes        
                .ENDIF

                add     nLength, ax

;---- Set Font, Draw the Text

                INVOKE  CreateFontIndirect, ADDR logfont
                mov     hFont, ax
                INVOKE  SelectObject, hDC, ax
                mov     hFont, ax
                INVOKE  DrawText, hDC, ADDR cBuffer, nLength, ADDR TextRect,
                                        DT_NOCLIP OR DT_CENTER
                INVOKE  SelectObject, hDC, hFont
                INVOKE  DeleteObject, ax

;---- If Iconized, draw rectangle with transparent background

                .IF Iconized

                        INVOKE  GetStockObject, HOLLOW_BRUSH
                        INVOKE  SelectObject, hDC, ax

                        INVOKE  CreatePen, PS_SOLID OR PS_INSIDEFRAME, 2, 0
                        INVOKE  SelectObject, hDC, ax
                        push    ax

                        INVOKE  Rectangle, hDC, TextRect.left, TextRect.top,
                                        TextRect.right, TextRect.bottom

                        INVOKE  GetStockObject, HOLLOW_BRUSH
                        INVOKE  SelectObject, hDC, ax
                        INVOKE  DeleteObject, ax

                        pop     ax
                        INVOKE  SelectObject, hDC, ax
                        INVOKE  DeleteObject, ax
                .ENDIF

;---- Check for Alarm

                xor     dx, dx
                mov     ax, hour
                mov     cx, 60t
                imul    cx
                add     ax, minutes          ; ax now holds the time in minutes

                .IF (TestAlarm)
                        .IF (EnableAlarm && (ax == AlarmTime))
                                mov     TestAlarm, FALSE
                                INVOKE  SetFocus, hWnd
                                INVOKE  InvertRect, hDC, ADDR TextRect
                                INVOKE  MessageBeep, MB_ICONASTERISK
                                INVOKE  InvertRect, hDC, ADDR TextRect
                                INVOKE  MessageBox, hWnd, ADDR szAlarmMsg,
                                    ADDR szAppName,MB_ICONEXCLAMATION OR MB_OK
                        .ENDIF
                .ELSE ; of TestAlarm                    ; if TestAlarm=0, means
                        .IF (ax != AlarmTime)           ; we sounded the alarm.
                                mov     TestAlarm, TRUE ; but, if time
                        .ENDIF                          ; changed, we should to
                .ENDIF                                  ; check again (allows
                                                        ; alarm every 24 hours)

                ret

PaintTime       ENDP

WndProc         PROC FAR PASCAL, hWnd:HWND, iMessage:WORD, wParam:SWORD,
                                 lParam:SDWORD
                ; Windows gives us: the handle of the Window, the Message ID,
                ; and two parameters for the message

                LOCAL   hDC:HDC, ps:PAINTSTRUCT, point:POINT
                ; locals: a handle to a device context, a paint structure,
                ;         a point structure

                .IF     (iMessage == WM_CREATE)
                        INVOKE  SetupTimer, hWnd, TIMER_SECS
                        INVOKE  Resize, hWnd
                        INVOKE  InvalidateRect, hWnd, NULL, FALSE

                .ELSEIF (iMessage == WM_TIMER)
                        INVOKE  InvalidateRect, hWnd, NULL, FALSE

                .ELSEIF (iMessage == WM_PAINT)
                        INVOKE  BeginPaint, hWnd, ADDR ps
                        mov     hDC, ax
                        .IF SetAlarm
                                INVOKE  PaintAlarm, hWnd, hDC
                        .ELSE
                                INVOKE  PaintTime, hWnd, hDC
                        .ENDIF
                        INVOKE  EndPaint, hWnd, ADDR ps

                .ELSEIF (iMessage == WM_SETFOCUS)
                        INVOKE  RedrawWindow, hWnd, NULL, NULL,
                                              RDW_FRAME OR RDW_UPDATENOW

                .ELSEIF (iMessage == WM_SIZE)
                        .IF ((wParam != SIZE_MINIMIZED) && Iconized)
                                mov     Iconized, FALSE
                                INVOKE  KillTimer, hWnd, 1
                                INVOKE  SetupTimer, hWnd, TIMER_SECS
                        .ENDIF
                        INVOKE  Resize, hWnd
                        INVOKE  RedrawWindow, hWnd, NULL, NULL,
                                              RDW_ERASE OR RDW_INVALIDATE
                
                .ELSEIF (iMessage == WM_DESTROY)
                        INVOKE  KillTimer, hWnd, 1
                        INVOKE  PostQuitMessage, 0

                .ELSEIF (iMessage==WM_LBUTTONDBLCLK)||(iMessage==WM_RBUTTONUP)
                        .IF SetAlarm
                                xor SetAlarm, TRUE
                                INVOKE  AlarmSetup, hWnd
                        .ELSE
                                mov     di, word ptr lParam
                                mov     point.x, di
                                mov     di, word ptr (lParam+2)
                                mov     point.y, di
                                INVOKE  ClientToScreen, hWnd, ADDR point
                                INVOKE  TrackPopupMenu, hMenu, TPM_LEFTALIGN,
                                        point.x, point.y, 0, hWnd, NULL          
                                INVOKE  InvalidateRect, hWnd, NULL, TRUE
                        .ENDIF

                .ELSEIF (iMessage == WM_LBUTTONDOWN)
                        INVOKE DefWindowProc, hWnd, WM_NCLBUTTONDOWN,
                                HTCAPTION, lParam

                .ELSEIF (iMessage == WM_COMMAND)

                        .IF (wParam == IDM_DATE)
                                xor     EnableDate, MF_CHECKED
                                INVOKE  CheckMenuItem,hMenu,wParam,EnableDate
                                INVOKE  Resize, hWnd
                                INVOKE  InvalidateRect, hWnd, NULL, FALSE                      

                        .ELSEIF (wParam == IDM_ALARM)
                                xor     EnableAlarm, MF_CHECKED
                                mov     TestAlarm, TRUE
                                INVOKE  CheckMenuItem,hMenu,wParam,EnableAlarm

                        .ELSEIF (wParam == IDM_SET)
                                mov     SetAlarm, TRUE
                                INVOKE  AlarmSetup, hWnd

                        .ELSEIF (wParam == IDM_ABOUT)
                                INVOKE  MessageBox, hWnd, ADDR szAboutText,
                                     ADDR szAppName, MB_ICONASTERISK OR MB_OK

                        .ELSEIF (wParam == IDM_ONTOP)
                                xor     AlwaysOnTop, MF_CHECKED
                                INVOKE  CheckMenuItem,hMenu,wParam,AlwaysOnTop
                                .IF AlwaysOnTop
                                        mov     ax, HWND_TOPMOST
                                .ELSE
                                        mov     ax, HWND_NOTOPMOST
                                .ENDIF

                                INVOKE  SetWindowPos, hWnd, ax,
                                        0, 0, 0, 0, SWP_NOMOVE OR SWP_NOSIZE
                        
                        .ELSEIF (wParam == IDM_EXIT)
                                INVOKE  KillTimer, hWnd, 1
                                INVOKE  PostQuitMessage, 0

                        .ELSEIF (wParam == IDM_MINIMIZE)
                                mov     Iconized, TRUE
                                INVOKE  KillTimer, hWnd, 1
                                INVOKE  SetupTimer, hWnd, TIMER_MINS
                                INVOKE  DefWindowProc, hWnd, WM_SYSCOMMAND,
                                                       SC_ICON, NULL

                        .ENDIF
                
                .ELSEIF (iMessage == WM_HSCROLL)
                        .IF (wParam == SB_PAGEDOWN)
                                add     AlarmTime, 10t
                        .ELSEIF (wParam == SB_LINEDOWN)
                                inc     AlarmTime
                        .ELSEIF (wParam == SB_PAGEUP)
                                sub     AlarmTime, 10t
                        .ELSEIF (wParam == SB_LINEUP)
                                dec     AlarmTime
                        .ELSEIF (wParam == SB_TOP)
                                mov     AlarmTime, MAXTIME
                        .ELSEIF (wParam == SB_BOTTOM)
                                mov     AlarmTime, 0t
                        .ELSEIF (wParam == SB_THUMBPOSITION)
                                mov     ax, word ptr lParam
                                mov     AlarmTime, ax
                        .ELSEIF (wParam == SB_THUMBTRACK)
                                mov     ax, word ptr lParam
                                mov     AlarmTime, ax
                        .ELSEIF (wParam == SB_LINEDOWN)
                                mov     ax, word ptr lParam
                                mov     AlarmTime, ax
                        .ENDIF
                                .IF (AlarmTime < 0)
                                        mov     AlarmTime, 0t
                                .ELSEIF (AlarmTime > MAXTIME)
                                        mov     AlarmTime, MAXTIME
                                .ENDIF
                        
                                INVOKE  SetScrollPos, hWndScrol, SB_CTL,
                                        AlarmTime, TRUE
                                INVOKE  InvalidateRect, hWnd,
                                                        ADDR TextRect, FALSE

                .ELSE
                                INVOKE  DefWindowProc, hWnd, iMessage,
                                                       wParam,lParam
                                jmp     doRet

                .ENDIF

                mov ax, 0
                cwd
doRet:
                ret

WndProc         ENDP


                END  __astart   ; so that the code of the application will
                                ; start with the Windows start-up code


اما شما می توانید یک بخش بحرانی برنامه را فقط با Assembly بنویسید. Cool
مثال ساده می زنم این:

void add(unsigned ling int X, unsigned long int Y, unsigned long int& intResult)0
{
_asm
{
push eax
move eax, X
add eax, Y
move intResult, eax
}
}

حالا می توانی بنویسی:
add(2, 4, l_intResultValue);0

این روش بهتر نیست؟ Tongue
اما مواظب باش حتی الآمکان از Assmbely در برنامه هات استفاده نکن. Amaze
چون وابستگی به محیط در برنامت ایجاد میکنه که ارزش نداره! At

راستی بر نامه بالا را می گذارم واسه Download: Cool
بابا شما بحث رو جدی گرفتید !!!!!!!!!!!!
اینها همه مال اسمبلی تحت ویندوز هست که کمتر استفاده می شه ( چون برنامه تحت ویندوز با اسمبلی کد نویسی زیادی داره )

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


*************************************************

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