-
-
[翻译]Win32asm tutorial (Asm.yeah.net) 的翻译文章
-
发表于: 2007-12-1 17:59 3560
-
Tutorial 1: The Basics
教程 1 :基本概念
________________________________________
This tutorial assumes that the reader knows how to use MASM. If you're not familiar with MASM, download win32asm.exe and study the text inside the package before going on with the tutorial. Good. You're now ready. Let's go!
这一课设想读者已经知道了如何使用MASM 。 如果你并不熟悉MASM ,在开始这一课之前请下载安装WIN32ASM.EXE并学习在安装包内的说明文当。好,你现在已经准备好了了,让我们开始吧!
Theory:
Win32 programs run in protected mode which is available since 80286. But 80286 is now history. So we only have to concern ourselves with 80386 and its descendants.
WIN32应用程序运行在保护模式下,保护模式用于自80286的计算机体系上。但是80286如今已经成为历史。所以我们只需要关心我们自己使用的80386及后续CPU即可。
Windows runs each Win32 program in separated virtual space. That means each Win32 program will have its own 4 GB address space. However, this doesn't mean every win32 program has 4GB of physical memory, only that the program can address any address in that range.
Windows中的每一个WIN32程序都在自己单独的,并相互隔离的虚拟地址空间中运行。那样意味着每一个WIN32程序将有属于它自己4GB的地址空间。然而,这并不意味着每一个WIN32程序的物理空间是4GB,而是仅能在4GB的空间内寻址。
Windows will do anything necessary to make the memory the program references valid. Of course, the program must adhere to the rules set by Windows, else it will cause the dreaded General Protection Fault. Each program is alone in its address space. This is in contrast to the situation in Win16. All Win16 programs can *see* each other. Not so under Win32. This feature helps reduce the chance of one program writing over other program's code/data.
Windows操作系统将做任何必须的事情,即完成4GB虚拟内存到物理内存的转换。当然,这个程序也必须遵守操作系统所设置的一些规则。否则,它将引起可怕的全局保护错误。每一个程序都在它独自的地址空间中。这和WIN16模式形成对比。在过去的WIN16模式下,所有的程序都可以彼此“看”到对方的内容。而在WIN32中,由于所有的程序都在自己独立的地址空间中运行,这种特征有助于减少一个程序改写另一个程序的代码或是数据的可能性。
Memory model is also drastically different from the old days of the 16-bit world. Under Win32, we need not be concerned with memory model or segments anymore! There's only one memory model: Flat memory model. There's no more 64K segments. The memory is a large continuous space of 4 GB. That also means you don't have to play with segment registers. You can use any segment register to address any point in the memory space. That's a GREAT help to programmers. This is what makes Win32 assembly programming as easy as C.
内存模式也彻底的不同于以往的16位世界,在WIN32中,我们再也不需要参与内存模式和段定义。这里仅有一种模式:平坦内存模式。它不再受64KB的限制。
它的内存大小是连续的4GB空间,那样意味着再也没必要和段寄存器打交道,你可以用任何段寄存器来存放任何在内存空间中的指针。(即寻址)这对程序员来说是很大的帮助。这也使得写WIN32 汇编程序变得和写C语言一样容易。
When you program under Win32, you must know some important rules. One such rule is that, Windows uses esi, edi, ebp and ebx internally and it doesn't expect the values in those registers to change. So remember this rule first: if you use any of those four registers in your callback function, don't ever forget to restore them before returning control to Windows. A callback function is your own function which is called by Windows. The obvious example is the windows procedure. This doesn't mean that you cannot use those four registers, you can. Just be sure to restore them back before passing control back to Windows.
当你在WIN32 中编程时, 你必须知道一些重要的规则。其中一条规则是这样,WINDOWS 系统并不检测在系统中使用的esi , edi ebp 和 ebx 这些寄存器的值被改变。所以,请记住第一条规则,如果在回调函数中用了上文四种寄存器中的任何一种,请不要忘记在把控制权返回给系统时恢复寄存器的值。回调函数是被WINOWS自身调用的函数。最明显的以个例子就是windows窗口程序。但这并部意味着你不能使用这四个寄存器。你当然能使用它们,只是你必须保证在把控制权传递给WINDOWS 之前把它们的值恢复。
Content:
内容
Here's the skeleton program. If you don't understand some of the codes, don't panic. I'll explain each of them later.
这里是程序的骨架,(框架)如果你不理解这些代码,没理由恐慌,我将在下面逐一解释它们。
.386
.MODEL Flat, STDCALL
.DATA
<Your initialized data>
......
.DATA?
<Your uninitialized data>
......
.CONST
<Your constants>
......
.CODE
<label>
<Your code>
.....
end <label>
That's all! Let's analyze this skeleton program.
就这些 ,让我们分析这个程序框架。
.386
This is an assembler directive, telling the assembler to use 80386 instruction set. You can also use .486, .586 but the safest bet is to stick to .386. There are actually two nearly identical forms for each CPU model. .386/.386p, .486/.486p. Those "p" versions are necessary only when your program uses privileged instructions. Privileged instructions are the instructions reserved by the CPU/operating system when in protected mode. They can only be used by privileged code, such as the virtual device drivers. Most of the time, your program will work in non-privileged mode so it's safe to use non-p versions.
这是一个汇编伪指令,它告诉汇编程序用80386的指令集。你同样也能用.486 , .586 但是.386是最安全的.对于同一种CPU,实际上有两种几乎相同的指令集存在. .386 / .386p .486/ .486p .这种带p 的模式仅当你的程序用到特权指令时才是必须的.特权指令是为CPU或在保护模式中的操作系统保留的指令,它们只能被用于有特权的代码.例如,虚拟设备驱动程序.其实,大多时候,,你的程序只工作于没有特权的模式,所以它用没p 的模式也同样安全.
.MODEL FLAT, STDCALL
.MODEL is an assembler directive that specifies memory model of your program. Under Win32, there's only on model, FLAT model.
STDCALL tells MASM about parameter passing convention. Parameter passing convention specifies the order of parameter passing, left-to-right or right-to-left, and also who will balance the stack frame after the function call.
.model 是一汇编伪指令.用于指定你的程序属于那种内存模式.win 32 中 ,仅有一种模式 “平坦模式”.
Stdcall 告诉MASM 关参数传递约定.参数传递约定指定了参数传递的顺序.从左到右 还是 从右到左 ,也同样指定了谁将在函数调用后来平衡堆栈结构.
Under Win16, there are two types of calling convention, C and PASCAL
C calling convention passes parameters from right to left, that is , the rightmost parameter is pushed first. The caller is responsible for balancing the stack frame after the call. For example, in order to call a function named foo(int first_param, int second_param, int third_param) in C calling convention the asm codes will look like this:
在win 16中,有两种类型的调用约定,C和PASCAL .
C调用约定从右到左传递参数,也就是说,最右边的参数最先入栈.调用者负责在函数调用后平衡堆栈结构.例如,为了调用函数名为FOO(int first param ,int second param ,int third param ),在C调用约定中的汇编代码像这样:
push [third_param] ; Push the third parameter 第三个参数入栈
push [second_param] ; Followed by the second第二个参数入栈
push [first_param] ; And the first第一个参数入栈
call foo
add sp, 12 ; The caller balances the stack frame
调用者平衡堆栈结构
PASCAL calling convention is the reverse of C calling convention. It passes parameters from left to right and the callee is responsible for the stack balancing after the call.
PASCAL 调用约定时完全相反于C调用约定,它从左到右传递参数并且由被调用者负责在调用后平衡堆栈结构.
Win16 adopts PASCAL convention because it produces smaller codes. C convention is useful when you don't know how many parameters will be passed to the function as in the case of wsprintf(). In the case of wsprintf(), the function has no way to determine beforehand how many parameters will be pushed on the stack, so it cannot do the stack balancing.
Win 16 采用PASCAL约定,因为它的代码量小.当你不知道像WSPRINTF()这样的函数有多少个参数将要被传递的情况下 C参数调用约定是很有用的.在win16 中,没有任何方法预先知道这个函数有多少个参数将要入栈,所以它也不能平衡堆栈.
STDCALL is the hybrid of C and PASCAL convention. It passes parameter from right to left but the callee is responsible for stack balancing after the call.Win32 platform use STDCALL exclusively. Except in one case: wsprintf(). You must use C calling convention with wsprintf().
Stdcall 是C和 PASCAL的混合约定.它的参数传递从右至左,但是被调用者负责在调用后平衡堆栈结构.WIN32平台只使用STDCALL ,但除了一个专例: wsprintf(). 你必须用C调用约定来使用WSPRINTF()
.DATA
.DATA?
.CONST
.CODE
All four directives are what's called section. You don't have segments in Win32, remember? But you can divide your entire address space into logical sections. The start of one section denotes the end of the previous section. There'are two groups of section: data and code. Data sections are divided into 3 categories:
这四条伪指令说明什么节区被调用.在win 32中,你并不需要断定义.记得吗?但是你能在逻辑节区里隔开你所有的地址空间.以个节区的开始表示着另外一个节区的结束.它们有两组节区:数据区和代码区. 数据区有三种类别:
• .DATA This section contains initialized data of your program.
这个节区包含你程序中已经初始化的数据
• .DATA? This section contains uninitialized data of your program.
这个节区包含你程序中未初始化的数据
• Sometimes you just want to preallocate some memory but don't want to initialize it. This section is for that purpose. The advantage of uninitialized data is: it doesn't take space in the executable file. For example, if you allocate 10,000 bytes in your .DATA? section, your executable is not bloated up 10,000 bytes. Its size stays much the same. You only tell the assembler how much space you need when the program is loaded into memory, that's all.
有时候你只使像再分配一些空间但是并不想去初始化它.这个节区就是为了这个用途.未初始化数据的优势是:它并不占用可执行文件的空间.例如:
如果你分配了10,000 个字节给你的.DATA? 节区,但是你的可执行文件并没有增加10,000个字节。它的大小仍然没有改变。它仅仅是告诉汇编程序,当你的程序被装入内存的时候你需要多少空间。
• .CONST This section contains declaration of constants used by your program. Constants in this section can never be modified in your program. They are just *constant*.
这个节区包含被你程序使用的常量的声明。这个节区中的常数在程序中永远不能被修改。它们仅仅是*恒量*;
You don't have to use all three sections in your program. Declare only the section(s) you want to use.
在你的程序中,不时这三个节区都必须使用。你仅仅需要声明你想使用的节区就可以。(当然也可以全都声明。即三个节区在一个程序中可以同时存在。)
There's only one section for code: .CODE. This is where your codes reside.
至于代码,它仅有一个节区。 .CODE 这是代码居住的地方。
<label> ; <start>
end <label> ; end <start>
where <label> is any arbitrary label is used to specify the extent of your code. Both labels must be identical. All your codes must reside between <label> and end <label>
开始标号可以使任意的标号,用于表示你的代码到什么程度。即,从那里开始,到哪里结束。 两个标号必须是一样的。你所有的代码都必须居住在这两个标号之间。
________________________________________
文章来源于 Iczelion's asm page
风向改变译
教程 1 :基本概念
________________________________________
This tutorial assumes that the reader knows how to use MASM. If you're not familiar with MASM, download win32asm.exe and study the text inside the package before going on with the tutorial. Good. You're now ready. Let's go!
这一课设想读者已经知道了如何使用MASM 。 如果你并不熟悉MASM ,在开始这一课之前请下载安装WIN32ASM.EXE并学习在安装包内的说明文当。好,你现在已经准备好了了,让我们开始吧!
Theory:
Win32 programs run in protected mode which is available since 80286. But 80286 is now history. So we only have to concern ourselves with 80386 and its descendants.
WIN32应用程序运行在保护模式下,保护模式用于自80286的计算机体系上。但是80286如今已经成为历史。所以我们只需要关心我们自己使用的80386及后续CPU即可。
Windows runs each Win32 program in separated virtual space. That means each Win32 program will have its own 4 GB address space. However, this doesn't mean every win32 program has 4GB of physical memory, only that the program can address any address in that range.
Windows中的每一个WIN32程序都在自己单独的,并相互隔离的虚拟地址空间中运行。那样意味着每一个WIN32程序将有属于它自己4GB的地址空间。然而,这并不意味着每一个WIN32程序的物理空间是4GB,而是仅能在4GB的空间内寻址。
Windows will do anything necessary to make the memory the program references valid. Of course, the program must adhere to the rules set by Windows, else it will cause the dreaded General Protection Fault. Each program is alone in its address space. This is in contrast to the situation in Win16. All Win16 programs can *see* each other. Not so under Win32. This feature helps reduce the chance of one program writing over other program's code/data.
Windows操作系统将做任何必须的事情,即完成4GB虚拟内存到物理内存的转换。当然,这个程序也必须遵守操作系统所设置的一些规则。否则,它将引起可怕的全局保护错误。每一个程序都在它独自的地址空间中。这和WIN16模式形成对比。在过去的WIN16模式下,所有的程序都可以彼此“看”到对方的内容。而在WIN32中,由于所有的程序都在自己独立的地址空间中运行,这种特征有助于减少一个程序改写另一个程序的代码或是数据的可能性。
Memory model is also drastically different from the old days of the 16-bit world. Under Win32, we need not be concerned with memory model or segments anymore! There's only one memory model: Flat memory model. There's no more 64K segments. The memory is a large continuous space of 4 GB. That also means you don't have to play with segment registers. You can use any segment register to address any point in the memory space. That's a GREAT help to programmers. This is what makes Win32 assembly programming as easy as C.
内存模式也彻底的不同于以往的16位世界,在WIN32中,我们再也不需要参与内存模式和段定义。这里仅有一种模式:平坦内存模式。它不再受64KB的限制。
它的内存大小是连续的4GB空间,那样意味着再也没必要和段寄存器打交道,你可以用任何段寄存器来存放任何在内存空间中的指针。(即寻址)这对程序员来说是很大的帮助。这也使得写WIN32 汇编程序变得和写C语言一样容易。
When you program under Win32, you must know some important rules. One such rule is that, Windows uses esi, edi, ebp and ebx internally and it doesn't expect the values in those registers to change. So remember this rule first: if you use any of those four registers in your callback function, don't ever forget to restore them before returning control to Windows. A callback function is your own function which is called by Windows. The obvious example is the windows procedure. This doesn't mean that you cannot use those four registers, you can. Just be sure to restore them back before passing control back to Windows.
当你在WIN32 中编程时, 你必须知道一些重要的规则。其中一条规则是这样,WINDOWS 系统并不检测在系统中使用的esi , edi ebp 和 ebx 这些寄存器的值被改变。所以,请记住第一条规则,如果在回调函数中用了上文四种寄存器中的任何一种,请不要忘记在把控制权返回给系统时恢复寄存器的值。回调函数是被WINOWS自身调用的函数。最明显的以个例子就是windows窗口程序。但这并部意味着你不能使用这四个寄存器。你当然能使用它们,只是你必须保证在把控制权传递给WINDOWS 之前把它们的值恢复。
Content:
内容
Here's the skeleton program. If you don't understand some of the codes, don't panic. I'll explain each of them later.
这里是程序的骨架,(框架)如果你不理解这些代码,没理由恐慌,我将在下面逐一解释它们。
.386
.MODEL Flat, STDCALL
.DATA
<Your initialized data>
......
.DATA?
<Your uninitialized data>
......
.CONST
<Your constants>
......
.CODE
<label>
<Your code>
.....
end <label>
That's all! Let's analyze this skeleton program.
就这些 ,让我们分析这个程序框架。
.386
This is an assembler directive, telling the assembler to use 80386 instruction set. You can also use .486, .586 but the safest bet is to stick to .386. There are actually two nearly identical forms for each CPU model. .386/.386p, .486/.486p. Those "p" versions are necessary only when your program uses privileged instructions. Privileged instructions are the instructions reserved by the CPU/operating system when in protected mode. They can only be used by privileged code, such as the virtual device drivers. Most of the time, your program will work in non-privileged mode so it's safe to use non-p versions.
这是一个汇编伪指令,它告诉汇编程序用80386的指令集。你同样也能用.486 , .586 但是.386是最安全的.对于同一种CPU,实际上有两种几乎相同的指令集存在. .386 / .386p .486/ .486p .这种带p 的模式仅当你的程序用到特权指令时才是必须的.特权指令是为CPU或在保护模式中的操作系统保留的指令,它们只能被用于有特权的代码.例如,虚拟设备驱动程序.其实,大多时候,,你的程序只工作于没有特权的模式,所以它用没p 的模式也同样安全.
.MODEL FLAT, STDCALL
.MODEL is an assembler directive that specifies memory model of your program. Under Win32, there's only on model, FLAT model.
STDCALL tells MASM about parameter passing convention. Parameter passing convention specifies the order of parameter passing, left-to-right or right-to-left, and also who will balance the stack frame after the function call.
.model 是一汇编伪指令.用于指定你的程序属于那种内存模式.win 32 中 ,仅有一种模式 “平坦模式”.
Stdcall 告诉MASM 关参数传递约定.参数传递约定指定了参数传递的顺序.从左到右 还是 从右到左 ,也同样指定了谁将在函数调用后来平衡堆栈结构.
Under Win16, there are two types of calling convention, C and PASCAL
C calling convention passes parameters from right to left, that is , the rightmost parameter is pushed first. The caller is responsible for balancing the stack frame after the call. For example, in order to call a function named foo(int first_param, int second_param, int third_param) in C calling convention the asm codes will look like this:
在win 16中,有两种类型的调用约定,C和PASCAL .
C调用约定从右到左传递参数,也就是说,最右边的参数最先入栈.调用者负责在函数调用后平衡堆栈结构.例如,为了调用函数名为FOO(int first param ,int second param ,int third param ),在C调用约定中的汇编代码像这样:
push [third_param] ; Push the third parameter 第三个参数入栈
push [second_param] ; Followed by the second第二个参数入栈
push [first_param] ; And the first第一个参数入栈
call foo
add sp, 12 ; The caller balances the stack frame
调用者平衡堆栈结构
PASCAL calling convention is the reverse of C calling convention. It passes parameters from left to right and the callee is responsible for the stack balancing after the call.
PASCAL 调用约定时完全相反于C调用约定,它从左到右传递参数并且由被调用者负责在调用后平衡堆栈结构.
Win16 adopts PASCAL convention because it produces smaller codes. C convention is useful when you don't know how many parameters will be passed to the function as in the case of wsprintf(). In the case of wsprintf(), the function has no way to determine beforehand how many parameters will be pushed on the stack, so it cannot do the stack balancing.
Win 16 采用PASCAL约定,因为它的代码量小.当你不知道像WSPRINTF()这样的函数有多少个参数将要被传递的情况下 C参数调用约定是很有用的.在win16 中,没有任何方法预先知道这个函数有多少个参数将要入栈,所以它也不能平衡堆栈.
STDCALL is the hybrid of C and PASCAL convention. It passes parameter from right to left but the callee is responsible for stack balancing after the call.Win32 platform use STDCALL exclusively. Except in one case: wsprintf(). You must use C calling convention with wsprintf().
Stdcall 是C和 PASCAL的混合约定.它的参数传递从右至左,但是被调用者负责在调用后平衡堆栈结构.WIN32平台只使用STDCALL ,但除了一个专例: wsprintf(). 你必须用C调用约定来使用WSPRINTF()
.DATA
.DATA?
.CONST
.CODE
All four directives are what's called section. You don't have segments in Win32, remember? But you can divide your entire address space into logical sections. The start of one section denotes the end of the previous section. There'are two groups of section: data and code. Data sections are divided into 3 categories:
这四条伪指令说明什么节区被调用.在win 32中,你并不需要断定义.记得吗?但是你能在逻辑节区里隔开你所有的地址空间.以个节区的开始表示着另外一个节区的结束.它们有两组节区:数据区和代码区. 数据区有三种类别:
• .DATA This section contains initialized data of your program.
这个节区包含你程序中已经初始化的数据
• .DATA? This section contains uninitialized data of your program.
这个节区包含你程序中未初始化的数据
• Sometimes you just want to preallocate some memory but don't want to initialize it. This section is for that purpose. The advantage of uninitialized data is: it doesn't take space in the executable file. For example, if you allocate 10,000 bytes in your .DATA? section, your executable is not bloated up 10,000 bytes. Its size stays much the same. You only tell the assembler how much space you need when the program is loaded into memory, that's all.
有时候你只使像再分配一些空间但是并不想去初始化它.这个节区就是为了这个用途.未初始化数据的优势是:它并不占用可执行文件的空间.例如:
如果你分配了10,000 个字节给你的.DATA? 节区,但是你的可执行文件并没有增加10,000个字节。它的大小仍然没有改变。它仅仅是告诉汇编程序,当你的程序被装入内存的时候你需要多少空间。
• .CONST This section contains declaration of constants used by your program. Constants in this section can never be modified in your program. They are just *constant*.
这个节区包含被你程序使用的常量的声明。这个节区中的常数在程序中永远不能被修改。它们仅仅是*恒量*;
You don't have to use all three sections in your program. Declare only the section(s) you want to use.
在你的程序中,不时这三个节区都必须使用。你仅仅需要声明你想使用的节区就可以。(当然也可以全都声明。即三个节区在一个程序中可以同时存在。)
There's only one section for code: .CODE. This is where your codes reside.
至于代码,它仅有一个节区。 .CODE 这是代码居住的地方。
<label> ; <start>
end <label> ; end <start>
where <label> is any arbitrary label is used to specify the extent of your code. Both labels must be identical. All your codes must reside between <label> and end <label>
开始标号可以使任意的标号,用于表示你的代码到什么程度。即,从那里开始,到哪里结束。 两个标号必须是一样的。你所有的代码都必须居住在这两个标号之间。
________________________________________
文章来源于 Iczelion's asm page
风向改变译
赞赏
他的文章
- [原创]导入表静态特征免杀 8079
- [翻译]sulley 网络协议Fuzzing 测试文档 15635
- [原创][讨论]Tx 第三题的两个正向函数 8712
- [原创][原创]第二题答案 3490
- [原创]腾讯安全第一题 3609
看原图
赞赏
雪币:
留言: