Chapter 7: Examples of Simple Programs

Examples are essential for studying programming. I also learned on the examples.

In this chapter, I start with a detailed description of the WM_PAINT message. In Chapter 3, you considered this message but didn't use it. This was because the program window contained only controlsno text information or graphics. Now, I am going to correct this situation. Besides the WM_PAINT message, you will also consider various problems related to Windows programming.

Outputting Text into a Window

Listing 7.1 contains an example of a simple Windows program. If you only start to develop Windows applications, you'll find lots of new ideas in this listing. Therefore, start with a detailed description of this program.

  • In this program, the colors of the window background and text are defined on the basis of combinations of three colors: red, green, and blue. The color is set by a 32-bit number. The first byte specifies the intensity of red, the second byte specifies the intensity of green, and the third byte specifies the intensity of blue. The last byte is set to zero. The mechanism of generating this number is illustrated by the definition of the RGBW constant.

  • Window background color is set by defining a brush through the CreateSolidBrush function. A brush is a bitmap used by the system for filling solid areas.

  • Because the WM_PAINT message is sent by the system when redrawing window, the contents of the program window must be redrawn when receiving this message.

    This program outputs only one text string. To output this information into the window, it is first necessary to get the window context (also known as device context). From a programmer's point of view, this device context is simply a number used for ensuring communication between a program and its window As a rule, the device context is defined by calling the GetDC function. When receiving the WM_PAINT message, the program acquires the device context by calling the BeginPaint function. The argument of this function is the pointer to the special structure PAINTSTR; however, the fields of this structure are not used in this program.

  • I hope that you have already guessed on the basis of the program listingtext output is carried out using the OutText function. Before calling this function, you define the background and foreground colors by calling the SetBkColor and setTextColor functions. Background color, naturally, is the same as window color.

  • Now, it is necessary to pay attention to the coordinate system. Its center is in the top left corner of the window, the Y-axis is directed downward, and the X-axis is directed rightward. This variant is commonly adopted for graphical screens.

  • Another important aspect relates to text output into the window. The length of the string that must be displayed in the window is one of parameters of the OutText function. At this point, there are several important aspects that should be noted There are several methods of determining the output string length (minus the trailing 0). For example, you can use the SIZEOF or LENGTHOF operators of a macroassembler. However, Turbo Assembler lacks these operators. It is possible to resolve this discrepancy by placing a label in the end of the string or by using obsolete LENGTH and SIZE directives. However, I hope that you have already grasped the idea that to ensure compatibility and portability between MASM32 and TASM32, it is wise to avoid using macros. Moreover, because you are using string definitions according to C language conventions, it would be natural to define string functions {see the note at the end of this chapter). In this example, I have defined the function that returns the string length. Don't be confused because this function returns the result into the EBX register. It is simply more convenient . Besides, functions have another important advantage over macro tools, namely, they get the string length at run time instead of compile time.

Now, to ensure that this program can be compiled using Turbo Assembler, it is necessary to carry out the same manipulations as before, namely, to delete all @N suffixes and to include the IMPORT32.LIB library.

Listing 7.1: The simplest program that performs text output
image from book
 ; The TEXT1.INC file ; Constants ; The message arrives when the window is closed WM_DESTROY       equ 2 ; The message arrives when the window is created WM_CREATE        equ 1 ; The message arrives when the window must be redrawn WM_PAINT         equ 0Fh ; Window properties CS_VREDRAW       equ 1h CS_HREDRAW       equ 2h CS_GLOBALCLASS   equ 4000h WS_OVERLAPPEDWINDOW equ 000CF0000H Stylcl           equ CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS DX0              equ 300 DY0              equ 200 ; Color components RED              equ 50 GREEN            equ 50 BLUE             equ 255 RGBW             equ (RED or (GREEN shl 8)) or (BLUE shl 16) RGBT             equ 255 ; Red ; Standard icon identifier IDI_APPLICATION equ 32512 ; Cursor identifier IDC_CROSS       equ 32515 ; Normal display mode SW_SHOWNORMAL equ 1 ; Prototypes of external procedures EXTERN  CreateWindowExA@48:NEAR EXTERN  DefWindowProcA@16:NEAR EXTERN  DispatchMessageA@4:NEAR EXTERN  ExitProcess@4:NEAR EXTERN  GetMessageA@16:NEAR EXTERN  GetModuleHandleA@4:NEAR EXTERN  LoadCursorA@8:NEAR EXTERN  LoadIconA@8:NEAR EXTERN  PostQuitMessage@4:NEAR EXTERN  RegisterClassA@4:NEAR EXTERN  ShowWindow@8:NEAR EXTERN  TranslateMessage@4:NEAR EXTERN  UpdateWindow@4:NEAR EXTERN  BeginPaint@8:NEAR EXTERN  EndPaint@8:NEAR EXTERN  TextOutA@20:NEAR EXTERN  GetStockObject@4:NEAR EXTERN  CreateSolidBrush@4:NEAR EXTERN  SetBkColor@8:NEAR EXTERN  SetTextColor@8:NEAR ; Structures ; Message structure MSGSTRUCT STRUC        MSHWND           DD ? ; Identifier of the window                              ; that receives the message        MSMESSAGE        DD ? ; Message identifier        MSWPARAM         DD ? ; Additional information about the message        MSLPARAM         DD ? ; Additional information about the message        MSTIME           DD ? ; Time the message was sent        MSPT             DD ? ; Cursor position when this message was sent MSGSTRUCT ENDS ;-------- WNDCLASS STRUC        CLSSTYLE         DD ? ; Window style        CLSLPFNWNDPROC   DD ? ; Pointer to the window procedure        CLSCBCLSEXTRA    DD ? ; Information about auxiliary bytes                              ; for this structure        CLSCBWNDEXTRA    DD ? ; Information about auxiliary bytes                              ; for the window        CLSHINSTANCE     DD ? ; Application descriptor        CLSHICON         DD ? ; Window icon identifier        CLSHCURSOR       DD ? ; Window cursor identifier        CLSHBRBACKGROUND DD ? ; Window brush identifier        MENNAME          DD ? ; Identifier of the menu name        CLSNAME          DD ? ; Specifies the name for the window class WNDCLASS ENDS ;-------- PAINTSTR STRUC     hdc    DWORD 0     fErase DWORD 0     left   DWORD 0     top    DWORD 0     right  DWORD 0     bottom DWORD 0     fRes   DWORD 0     fIncUp DWORD 0     Reserv DB 32 dup(0) PAINTSTR ENDS ; The TEXT1.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall ;--------------------------------------- include textl.inc ; Connecting libraries includelib c:\masm32 lib\user32.lib includelib c:\masm32 lib\Kernel32.lib includelib c:\masm32 lib'\gdi32.lib ;--------------------------------------- ; Data segment _DATA SEGMENT         NEWHWND        DD 0         MSG            MSGSTRUCT <?>         WC             WNDCLASS  <?>         PNT            PAINTSTR  <?>         HINST          DD 0         TITLENAME      DB 'Window text', 0         NAM            DB 'CLASS32', 0         XT             DWORD 30         YT             DWORD 30         TEXT           DB 'Text in the window is red', 0 _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application descriptor         PUSH  0         CALL  GetModuleHandleA@4         MOV   [HINST], EAX REG_CLASS: ; Fill the window structure ; Style         MOV   [WC.CLSSTYLE], stylcl ; Message-handling procedure         MOV   [WC.CLSLPFNWNDPROC], OFFSET WNDPROC         MOV   [WC.CLSCBCLSEXTRA], 0         MOV   [WC.CLSCBWNDEXTRA], 0         MOV   EAX,[HINST]         MOV   [WC.CLSHINSTANCE], EAX ; Window icon         PUSH  IDI_APPLICATION         PUSH  0         CALL  LoadIconA@8         MOV [WC.CLSHICON], EAX ;--------- Window cursor         PUSH  IDC_CROSS         PUSH  0         CALL  LoadCursorA@8         MOV   [WC.CLSHCURSOR], EAX ;---------         PUSH  RGBW ; Brush color         CALL  CreateSolidBrush@4 ; Create a brush         MOV   [WC.CLSHBRBACKGROUND], EAX         MOV   DWORD PTR [WC.MENNAME], 0         MOV   DWORD PTR [WC.CLSNAME], OFFSET NAM         PUSH  OFFSET WC         CALL  RegisterClassA@4 ; Create a window of the registered class         PUSH  0         PUSH  [HINST]         PUSH  0         PUSH  0         PUSH  DY0        ; DY0 - Window height         PUSH  DX0        ; DX0 - Window width         PUSH  100        ; The Y coordinate         PUSH  100        ; The X coordinate         PUSH  WS_OVERLAPPEDWINDOW         PUSH  OFFSET TITLENAME ; Window name         PUSH  OFFSET NAM       ; Class name         PUSH  0         CALL  CreateWindowExA@48 ; Error check         CMP   EAX, 0         JZ    _ERR         MOV   [NEWHWND], EAX ; Window descriptor ;------------------------         PUSH  SW_SHOWNORMAL         PUSH  [NEWHWND]         CALL  ShowWindow@8 ; Show the window that you have just created ;------------------------         PUSH  [NEWHWND]         CALL  UpdateWindow@4 ; Redraw the visible part of the window ; Message-processing loop MSG_LOOP:         PUSH  0         PUSH  0         PUSH  0         PUSH  OFFSET MSG         CALL  GetMessageA@16         CMP   AX, 0         JE    END_LOOP         PUSH  OFFSET MSG         CALL  TranslateMessage@4         PUSH  OFFSET MSG         CALL  DispatchMessageA@4         JMP   MSG_LOOP END_LOOP: ; Exit the program (terminate the process)         PUSH  [MSG.MSWPARAM]         CALL  ExitProcess@4 _ERR:         JMP   END_LOOP ; Window procedure ; Parameters in the stack ; [EBP+014H]     ; LPARAM ; [EBP+10H]    ; WAPARAM ; [EBP+0CH]    ; MES ; [EBP+8]      ; HWND WNDPROC    PROC         PUSH  EBP         MOV   EBP, ESP         PUSH  EBX         PUSH  ESI         PUSH  EDI         CMP   DWORD PTR [EBP+0CH], WM_DESTROY         JE    WMDESTROY         CMP   DWORD PTR [EBP+0CH], WM_CREATE         JE    WMCREATE         CMP   DWORD PTR [EBP+0CH], WM_PAINT         JE    WMPAINT         JMP   DEFWNDPROC WMPAINT: ;---------------         PUSH  OFFSET PNT         PUSH  DWORD PTR [EBP+08H]         CALL  BeginPaint@8         PUSH  EAX ; Save the context (descriptor) ;----------------Background color = window color         PUSH  RGBW         PUSH  EAX         CALL  SetBkColor@8 ;----------------Context         POP   EAX         PUSH  EAX ;----------------Text color (red)         PUSH  RGBT         PUSH  EAX         CALL  SetTextColor@8 ;----------------Context         POP,  EAX ;----------------Display text         PUSH  OFFSET TEXT         CALL  LENSTR         PUSH  EBX ; string length         PUSH  OFFSET TEXT ; String address         PUSH  YT  ; Y         PUSH  XT  ; X         PUSH  EAX ; Window context         CALL  TextOutA@20 ;----------------Close         PUSH  OFFSET PNT         PUSH  DWORD PTR [EBP+08H]         CALL  EndPaint@8         MOV   EAX, 0         JMP   FINISH WMCREATE:         MOV   EAX, 0         JMP   FINISH DEFWNDPROC:         PUSH  DWORD PTR [EBP+14H]         PUSH  DWORD PTR [EBP+10H]         PUSH  DWORD PTR [EBP+0CH]         PUSH  DWORD PTR [EBP+08H]         CALL  DefWindowProcA@16         JMP   FINISH WMDESTROY:         PUSH  0         CALL  PostQuitMessage@4 ; WM_QUIT         MOV   EAX, 0 FINISH:         POP   EDI         POP   ESI         POP   EBX         POP   EBP         RET   16 WNDPROC ENDP ;----------- Function -------------------------- ; String length [EBP+08H]  Pointer to the string LENSTR PROC         PUSH  EBP         MOV   EBP, ESP         PUSH  ESI         MOV   ESI, DWORD PTR [EBP+8]         XOR   EBX, EBX LBL1:         CMP   BYTE PTR [ESI], 0         JZ    LBL2         INC   EBX         INC   ESI         JMP   LBL1 LBL2:         POP   ESI         POP   EBP         RET   4 LENSTR ENDP _TEXT ENDS END START 
image from book
 

Now consider another example illustrating text output into the window. Now your task is more complicated. Aim at ensuring that the text string always remains in the middle of the window no matter what happens to it. To achieve it, you'll need to know the window size in pixels and the string length. The string length in pixels is defined using the GetTextExtentPoint32 function; to determine the window size, use the GetwindowRect function. When doing so, you'll need structures such as SIZET and RECT . I hope you understand how to determine the string position if its length and window size are given. I'll only mention again that it's necessary to take into account the height of the window header.

Listing 7.2: Keeping the text string in the center of the window
image from book
 ; The TEXT2.INC file ; Constants ; The message arrives when the window is closed WM_DESTROY          equ 2 ; The message arrives when the window is created WM_CREATE           equ 1 ; The message arrives when the window is redrawn WM_PAINT            equ 0Fh ; Window properties CS_VREDRAW          equ 1h CS_HREDRAW          equ 2h CS_GLOBALCLASS      equ 4000h WS_OVERLAPPEDWINDOW equ 000CF0000H stylcl              equ CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS DX0                 equ 300 DY0                 equ 200 ; Color components RED                 equ 80 GREEN               equ 80 BLUE                equ 255 RGBW                equ (RED or (GREEN shl 8)) or (BLUE shl 16) RGBT                equ 00FF00H ; Green ; Standard icon identifier IDI_APPLICATION     equ 32512 ; Cursor identifier IDC_CROSS           equ 32515 ; Window display mode is normal SW_SHOWNORMAL equ 1 ; Prototypes of external procedures EXTERN  CreateWindowExA@48:NEAR EXTERN  DefWindowProcA@16:NEAR EXTERN  DispatchMessageA@4:NEAR EXTERN  ExitProcess04:NEAR EXTERN  GetMessageA@16:NEAR EXTERN  GetModuleHandleA@4:NEAR EXTERN  LoadCursorA@ 8:NEAR EXTERN  LoadIconA@8:NEAR EXTERN  PostQuitMessage@4:NEAR EXTERN  RegisterClassA@4:NEAR EXTERN  ShowWindow@8:NEAR EXTERN  TranslateMessage@4:NEAR EXTERN  UpdateWindow@4:NEAR EXTERN  BeginPaint@8:NEAR EXTERN  EndPaint@8:NEAR EXTERN  TextOutA@20:NEAR EXTERN  GetStock0bject@4:NEAR EXTERN  CreateSolidBrush@4:NEAR EXTERN  SetBkColor@8:NEAR EXTERN  SetTextColor@8:NEAR EXTERN  GetTextExtentPoint32A@16:NEAR EXTERN  GetWindowRect@8:NEAR ; Structures ; Message structure MSGSTRUCT STRUC         MSHWND           DD ? ; Identifier of the window                               ; that receives the message         MSMESSAGE        DD ? ; Message identifier         MSWPARAM         DD ? ; Additional information about the message         MSLPARAM         DD ? ; Additional information about the message         MSTIME           DD ? ; Message sending time         MSPT             DD ? ; Cursor position when the message was sent MSGSTRUCT ENDS ;--------- WNDCLASS STRUC         CLSSTYLE         DD ? ; Window style         CLSLPFNWNDPROC   DD ? ; Pointer to the window procedure         CLSCBCLSEXTRA    DD ? ; Information about additional bytes for                               ; this structure         CLSCBWNDEXTRA    DD ? ; Information about additional bytes                               ; for the window         CLSHINSTANCE     DD ? ; Application descriptor         CLSHICON         DD ? ; Window icon identifier         CLSHCURSOR       DD ? ; Window cursor identifier         CLSHBRBACKGROUND DD ? ; Window brush identifier         MENNAME          DD ? ; Menu identifier name         CLSNAME          DD ? ; Specifies the window class name WNDCLASS ENDS ;--------- PAINTSTR STRUC         hdc     DWORD 0         fErase  DWORD 0         left    DWORD 0         top     DWORD 0         right   DWORD 0         bottom  DWORD 0         fRes    DWORD 0         fIncUp  DWORD 0         Reserv  DB 32 dup(0) PAINTSTR ENDS ; --------------- SIZET STRUC         X1      DWORD ?         Yl      DWORD ? SIZET ENDS RECT STRUC         L       DWORD ? ; XAbscissa of the top left corner         T       DWORD ? ; Y  Ordinate of the top left corner         R       DWORD ? ; X  Abscissa of the bottom right corner         B       DWORD ? ; Y  Ordinate of the bottom right corner RECT ENDS ; The TEXT2.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall ;---------------------------------------------- include text2.inc ; Directive to the linker to include libraries c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\gdi32.lib ;---------------------------------------------- ; Data segment _DATA SEGMENT         NEWHWND  DD 0         MSG      MSGSTRUCT <?>         WC       WNDCLASS  <?>         PNT      PAINTSTR  <?>         SZT      SIZET     <?>         RCT      RECT      <?>         HINST    DD 0         TITLENAME DB 'text in the Window', 0         NAM      DB 'CLASS32', 0         XT       DWORD ?         YT       DWORD ?         TEXT DB 'Text displayed in the window is green', 0         CONT     DWORD ? _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application descriptor         PUSH  0         CALL  GetModuleHandleA@4         MOV   [HINST], EAX REG_CLASS: ; Fill the window structure ; Style         MOV   [WC.CLSSTYLE], stylcl ; Message-handling procedure         MOV   [WC.CLSLPFNWNDPROC], OFFSET WNDPROC         MOV   [WC.CLSCBCLSEXTRA], 0         MOV   [WC.CLSCBWNDEXTRA], 0         MOV   EAX,[HINST]         MOV   [WC.CLSHINSTANCE], EAX ;----------Window icon PUSH IDI_APPLICATION         PUSH  0         CALL  LoadIconA@8 MOV [WC.CLSHICON], EAX ;---------- Window cursor         PUSH  IDC_CROSS         PUSH  0         CALL  LoadCursorA@8         MOV   [WC.CLSHCURSOR], EAX ;----------         PUSH  RGBW ; Brush color         CALL  CreateSolidBrush@4 ; Create a brush         MOV   [WC.CLSHBRBACKGROUND], EAX         MOV   DWORD PTR [WC.MENNAME], 0         MOV   DWORD PTR [WC.CLSNAME], OFFSET NAM         PUSH  OFFSET WC         CALL  RegisterClassA@4 ; Create a window of the registered class         PUSH  0         PUSH  [HINST]         PUSH  0         PUSH  0         PUSH  DY0              ; DY0 - Window height         PUSH  DX0       ; DX0  Window width         PUSH  100       ; The Y coordinate         PUSH  100       ; The X coordinate         PUSH  WS_OVERLAPPEDWINDOW         PUSH  OFFSET TITLENAME ; Window name         PUSH  OFFSET NAM       ; Class name         PUSH  0         CALL  CreateWindowExA@48 ; Check for error         CMP   EAX, 0         JZ    _ERR         MOV   [NEWHWND], EAX ; Window descriptor ;--------------------------------         PUSH  SW_SHOWNORMAL         PUSH  [NEWHWND]         CALL  ShowWindow@8 ; Display the newly created window ;--------------------------------         PUSH  [NEWHWND]         CALL  UpdateWindow@4 ; Redraw the visible part of the window                              ; Message processing MSG_LOOP:         PUSH  0         PUSH  0         PUSH  0         PUSH  OFFSET MSG         CALL  GetMessageA@16         CMP   AX, 0         JE    END_LOOP         PUSH  OFFSET MSG         CALL  TranslateMessage@4         PUSH  OFFSET MSG         CALL  DispatchMessageA@4         JMP   MSG_LOOP END_LOOP: ; Exit the program (close the process)         PUSH  [MSG.MSWPARAM]         CALL  ExitProcess@4 _ERR:         JMP   END_LOOP ;-------------------------------------------------------; window procedure ; Positions of the parameters in the stack ; [EBP+014H]  ; LPARAM ; [EBP+10H]   ; WAPARAM ; [EBP+0CH]   ; MES ; [EBP+8]     ; HWND WNDPROC    PROC         PUSH  EBP         MOV   EBP, ESP         PUSH  EBX         PUSH  ESI         PUSH  EDI         CMP   DWORD PTR [EBP+0CH], WM_DESTROY         JE    WMDESTROY         CMP   DWORD PTR [EBP+0CH], WM_CREATE         JE    WMCREATE         CMP   DWORD PTR [EBP+0CH], WM_PAINT         JE    WMPAINT         JMP   DEFWNDPROC WMPAINT: ;----------------         PUSH  OFFSET PNT         PUSH  DWORD PTR [EBP+08H]         CALL  BeginPaint@8         MOV   CONT, EAX ; Save the context (descriptor) ;----------------Background color = window color         PUSH  RGBW         PUSH  EAX         CALL  SetBkColor@8 ;----------------Text color (red)         PUSH  RGBT         PUSH  CONT         CALL  SetTextColor@8 ; Compute text length in pixels         PUSH  OFFSET TEXT         CALL  LENSTR         PUSH  EBX ; Save the string length         PUSH  OFFSET SZT         PUSH  EBX         PUSH  OFFSET TEXT         PUSH  CONT         CALL  GetTextExtentPoint32A@16 ;----------------Window size         PUSH  OFFSET RCT         PUSH  DWORD PTR [EBP+8]         CALL  GetWindowRect@8 ;----------------Compute coordinates         MOV   EAX, RCT.R         SUB   EAX, RCT.L         SUB   EAX, SZT.X1         SHR   EAX, 1 ; Text in the middle         MOV   XT, EAX         MOV   EAX, RCT.B         SUB   EAX, RCT.T         SHR   EAX, 1         SUB   EAX, 25 ; Take the window header into account         MOV   YT, EAX ;----------------Display text ; String length in the stack         PUSH  OFFSET TEXT         PUSH  YT         PUSH  XT         PUSH  CONT         CALL  TextOutA@20 ;---------------- Close context         PUSH  OFFSET PNT         PUSH  DWORD PTR [EBP+08H]         CALL  EndPaint@8         MOV   EAX, 0         JMP   FINISH WMCREATE:         MOV   EAX, 0         JMP   FINISH DEFWNDPROC:         PUSH  DWORD PTR [EBP+14H]         PUSH  DWORD PTR [EBP+10H]         PUSH  DWORD PTR [EBP+0CH]         PUSH  DWORD PTR [EBP+08H]         CALL  DefWindowProcA@16         JMP   FINISH WMDESTROY:         PUSH  0         CALL  PostQuitMessage@4 ; WM_QUIT         MOV   EAX, 0 FINISH:         POP   EDI         POP   ESI         POP   EBX         POP   EBP         RET   16 WNDPROC ENDP ; String length ; String pointer is in the word located by the [EBP+8] address LENSTR PROC         PUSH  EBP         MOV   EBP, ESP         PUSH  ESI         MOV   ESI, DWORD PTR [EBP+8]         XOR   EBX, EBX LBL1:         CMP   BYTE PTR [ESI], 0         JZ    LBL2         INC   EBX         INC   ESI         JMP   LBL1 LBL2:         POP   ESI         POP   EBP         RET   4 LENSTR ENDP _TEXT ENDS END START 
image from book
 

I can't help admiring the possibilities that an assembler provides to programmers. You can pass parameters through the stack or, if desired, through registers. If you want to, you can save the registers' procedure beginning; if you don't want it, you can do without it. Assembler code can be improved beyond any perceivable limits of perfection . By the way, for the fans of string commands, I'll provide another procedure for determining the string length based on the SCAS microprocessor command. This command allows you to search for the required element (byte SCASB , word SCASW , and double word SCASD ) within a string.

 ; String length  [EBP+08H] LENSTR PROC         PUSH   EBP         MOV    EBP, ESP         PUSH   EAX ;------------------         CLD         MOV    EDI, DWORD PTR [EBP+08H]         MOV    EBX, EDI         MOV    ECX, 100 ; Limit the string length         XOR    AL, AL         REPNE  SCASB ; Find symbol 0         SUB    EDI, EBX ; String length, including 0         MOV    EBX, EDI         DEC    EBX ; String length is saved here ;------------------         POP     EAX         POP     EBP         RET     4         LENSTR  ENDP 


The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net