⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tut2.html

📁 WINDOWS程序员使用指南--汇编基础
💻 HTML
📖 第 1 页 / 共 2 页
字号:
  the function pro</font></font><font face="Arial"><font size=-1><font color="#CCCCCC">totypes 
  from kernel32.dll. That file is kernel32.inc. If you open it with a text editor, 
  you will see that it's full of function prototypes for kernel32.dll. If you 
  don't include kernel32.inc, you can still call ExitProcess but only with simple 
  call syntax. You won't be able to </font><font color="#FFFF99">invoke</font><font color="#CCCCCC"> 
  the function. The point here is that: in order to invoke a function, you have 
  to put its function prototype somewhere in the source code. In the above example, 
  if you don't include kernel32.inc, you can define the function prototype for 
  ExitProcess anywhere in the source code above the invoke command and it will 
  work. The include files are there to save you the work of typing out the prototypes 
  yourself so use them whenever you can.</font></font></font> <br>
  <font face="Arial"><font size=-1><font color="#CCCCCC">Now we encounter a new 
  directive, </font><font color="#FFFF99">includelib</font><font color="#CCCCCC">. 
  includelib doesn't work like </font><font color="#FFFF99">include</font><font color="#CCCCCC">. 
  It 's only a way to tell the assembler what import library your program uses. 
  When the assembler sees an includelib directive, it puts a linker command into 
  the object file so that the linker knows what import libraries your program 
  needs to link with. You're not forced to use includelib though. You can specify 
  the names of the import libraries in the command line of the linker but believe 
  me, it's tedious and the command line can hold only 128 characters.</font></font></font> 
<p><font face="Arial"><font size=-1><font color="#CCCCCC">Now save the
example under the name </font><font color="#FFFF99">msgbox.asm</font><font color="#CCCCCC">.</font><font color="#CCCCFF">
</font><font color="#CCCCCC">Assuming that ml.exe is in your path, assemble
msgbox.asm with:</font></font></font>
<ul><font face="Arial"><font color="#66FF66"><font size=-1>ml&nbsp; /c&nbsp;
/coff&nbsp; /Cp msgbox.asm</font></font></font>
<li>
<font face="Arial"><font size=-1><font color="#CC0000">/c</font><font color="#CCCCCC">
tells MASM to assemble only. Do not invoke link.exe. Most of the time,
you would not want to call link.exe automatically since you may have to
perform some other tasks prior to calling link.exe.</font></font></font></li>

<br><font face="Arial"><font size=-1><font color="#CC0000">/coff </font><font color="#CCCCCC">tells
MASM to create .obj file in </font><font color="#FFFF99">COFF</font><font color="#CCCCCC">
format. MASM uses a variation of </font><font color="#FFFF99">COFF</font><font color="#CCCCCC">
(Common Object File Format) which is used under Unix as its own object
and executable file format.</font></font></font>
<br><font face="Arial"><font size=-1><font color="#CC0000">/Cp</font><font color="#CCCCCC">
tells MASM to preserve case of user identifiers. If you use hutch's </font><font color="#FFFF99">MASM32</font><font color="#CCCCCC">
package, you may put "</font><font color="#FFFF99">option casemap:none</font><font color="#CCCCCC">"
at the head of your source code, just below </font><font color="#FFFF99">.model</font><font color="#CCCCCC">
directive to achieve the same effect.</font></font></font></ul>
<font face="Arial"><font color="#CCCCCC"><font size=-1>After you successfully
assemble msgbox.asm, you will get msgbox.obj. msgbox.obj is an object file.
An object file is only one step away from an executable file. It contains
the instructions/data in binary form. What is lacking is some fixups of
addresses by the linker.</font></font></font>
<p><font face="Arial"><font color="#CCCCCC"><font size=-1>Then go on with
link:</font></font></font>
<ul><font face="Arial"><font color="#66FF33"><font size=-1>link /SUBSYSTEM:WINDOWS&nbsp;
/LIBPATH:c:\masm32\lib&nbsp; msgbox.obj</font></font></font></ul>

<blockquote><font face="Arial"><font size=-1><font color="#CC0000">/SUBSYSTEM:WINDOWS</font><font color="#CCCCCC">&nbsp;
informs Link what sort of executable this program is</font></font></font>
<br><font face="Arial"><font size=-1><font color="#CC0000">/LIBPATH:&lt;path
to import library></font><font color="#CCCCCC"> tells Link where the import
libraries are. If you use MASM32, they will be in MASM32\lib folder.</font></font></font></blockquote>
<font face="Arial"><font color="#CCCCCC"><font size=-1>Link reads in the
object file and fixes it with addresses from the import libraries. When
the process is finished you get msgbox.exe.</font></font></font>
<p><font face="Arial"><font color="#CCCCCC"><font size=-1>Now you get msgbox.exe.
Go on, run it. You'll find that it does nothing. Well, we haven't put anything
interesting into it yet. But it's a Windows program nonetheless. And look
at its size! In my PC, it is 1,536 bytes.</font></font></font>
<p><font face="Arial"><font color="#CCCCCC"><font size=-1>Next we're going
to put in a message box. Its function prototype is:</font></font></font>
<p><b><font face="Arial"><font color="#FFCC00"><font size=-1>MessageBox
PROTO hwnd:DWORD, lpText:DWORD, lpCaption:DWORD, uType:DWORD</font></font></font></b>
<blockquote><font face="Arial"><font size=-1><font color="#FFFF99">hwnd</font><font color="#CCCCCC">
is the handle to parent window</font><font color="#CCCCFF">.</font><font color="#CCCCCC">
You can think of a handle as a number that represents the window you're
referrring to. Its value is not important to you. You only remember that
it represents the window. When you want to do anything with the window,
you must refer to it by its handle.</font></font></font>
<br><font face="Arial"><font size=-1><font color="#FFFF99">lpText</font><font color="#CCCCCC">
is a pointer to the text you want to display in the client area of the
message box. A pointer is really an address of something. A pointer to
text string==The address of that string.</font></font></font>
<br><font face="Arial"><font size=-1><font color="#FFFF99">lpCaption</font><font color="#CCCCCC">
is a pointer to the caption of the message box</font></font></font>
<br><font face="Arial"><font size=-1><font color="#FFFF99">uType</font><font color="#CCCCCC">
specifies the icon and the number and type of buttons on the message box</font></font></font></blockquote>
<font face="Arial"><font color="#CCCCCC"><font size=-1>Let's modify msgbox.asm
to include the message box.</font></font></font>
<br>&nbsp;
<p><font face="Arial"><font color="#FFFF99"><font size=-1>.386</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>.model flat,stdcall</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>option casemap:none</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>include \masm32\include\windows.inc</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>include \masm32\include\kernel32.inc</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>includelib \masm32\lib\kernel32.lib</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>include \masm32\include\user32.inc</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>includelib \masm32\lib\user32.lib</font></font></font>
<p><font face="Arial"><font color="#FFFF99"><font size=-1>.data</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>MsgBoxCaption&nbsp;
db "Iczelion Tutorial No.2",0</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>MsgBoxText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
db "Win32 Assembly is Great!",0</font></font></font>
<p><font face="Arial"><font color="#FFFF99"><font size=-1>.code</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>start:</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>invoke MessageBox,
NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>invoke ExitProcess,
NULL</font></font></font>
<br><font face="Arial"><font color="#FFFF99"><font size=-1>end start</font></font></font>
<p><font face="Arial"><font color="#CCCCCC"><font size=-1>Assemble and
run it. You will see a message box displaying the text "Win32 Assembly
is Great!".</font></font></font>
<p><font face="Arial"><font color="#CCCCCC"><font size=-1>Let's look again
at the source code.</font></font></font>
<br><font face="Arial"><font color="#CCCCCC"><font size=-1>We define two
zero-terminated strings in .data section. Remember that every ANSI string
in Windows must be terminated by NULL (0 hexadecimal).</font></font></font>
<br><font face="Arial"><font color="#CCCCCC"><font size=-1>We use two constants,
NULL and MB_OK. Those constants are documented in windows.inc. So you can
refer to them by name instead of the values. This improves readability
of your source code.</font></font></font>
<br><font face="Arial"><font size=-1><font color="#CCCCCC">The </font><font color="#FFFF99">addr</font><font color="#CCCCCC">
operator is used to pass the address of a label to the function.</font><font color="#CCCCFF">
</font><font color="#CCCCCC">It's valid only in the context of invoke directive.
You can't use it to assign the address of a label to a register/variable,
for example. You can use </font><font color="#FFFF99">offset</font><font color="#CCCCCC">
instead of addr in the above example. However, there are some differences
between the two:</font></font></font>
<ol>
<li>
<font face="Arial"><font size=-1><font color="#FFFF99">addr</font><font color="#CCCCFF">
</font><font color="#CCCCCC">cannot handle forward reference while</font><font color="#CCCCFF">
</font><font color="#FFFF99">offset</font><font color="#CCCCFF"> </font><font color="#CCCCCC">can.
For example, if the label is defined somewhere further in the source code
than the invoke line, addr will not work.</font><font color="#CCCCFF"></font></font></font></li>

<blockquote><font face="Arial"><font color="#CCCCCC"><font size=-1>invoke
MessageBox,NULL, addr MsgBoxText,addr MsgBoxCaption,MB_OK</font></font></font>
<br><font face="Arial"><font color="#CCCCFF"><font size=-1>......</font></font></font>
<br><font face="Arial"><font color="#CCCCCC"><font size=-1>MsgBoxCaption&nbsp;
db "Iczelion Tutorial No.2",0</font></font></font>
<br><font face="Arial"><font color="#CCCCCC"><font size=-1>MsgBoxText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
db "Win32 Assembly is Great!",0</font></font></font></blockquote>
<font face="Arial"><font size=-1><font color="#CCCCCC">MASM will report
error. If you use</font><font color="#CCCCFF"> </font><font color="#FFFF99">offset</font><font color="#CCCCCC">
instead of</font><font color="#CCCCFF"> </font><font color="#FFFF99">addr</font><font color="#CCCCFF">
</font><font color="#CCCCCC">in the above code snippet, MASM will assemble
it happily.</font></font></font>
<li>
<font face="Arial"><font size=-1><font color="#FFFF99">addr</font><font color="#CCCCFF">
</font><font color="#CCCCCC">can handle local variables while</font><font color="#FFFF99">
offset</font><font color="#CCCCFF"> </font><font color="#CCCCCC">cannot</font><font color="#CCCCFF">.
</font><font color="#CCCCCC">A local variable is only some reserved space
in the stack. You will only know its address during runtime. </font><font color="#FFFF99">offset</font><font color="#CCCCCC">
is interpreted during assembly time by the assembler. So it's natural that
</font><font color="#FFFF99">offset</font><font color="#CCCCCC"> won't
work for local variables. </font><font color="#FFFF99">addr</font><font color="#CCCCCC">
is able to handle local variables because of the fact that the assembler
checks first whether the variable referred to by </font><font color="#FFFF99">addr</font><font color="#CCCCCC">
is a global or local one. If it's a global variable, it puts the address
of that variable into the object file. In this regard, it works like </font><font color="#FFFF99">offset</font><font color="#CCCCCC">.
If it's a local variable, it generates an instruction sequence like this
before it actually calls the function:</font><font color="#CCCCFF"></font></font></font></li>

<blockquote><font face="Arial"><font color="#999900"><font size=-1>lea
eax, LocalVar</font></font></font>
<br><font face="Arial"><font color="#999900"><font size=-1>push eax</font></font></font></blockquote>

<p><br><font face="Arial"><font color="#CCCCCC"><font size=-1>Since lea
can determine the address of a label at runtime, this works fine.</font></font></font></ol>

<hr WIDTH="100%">
<center><b><font face="Arial"><font color="#006600"><font size=-1>[<a href="http://win32asm.cjb.net">Iczelion's
Win32 Assembly HomePage</a>]</font></font></font></b></center>

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -