Push是四个字节对齐的,因此每次压入四个字节。
_asm关键字用于调用内联汇编程序,并且可以在c/c++语句中出现。它不能单独出现,必须后接汇编指令。如果其后面不接大括号,那么表示这行的其余部分是一条汇编语句。
:向eax中加入有效地址。
,表示异或。Xor ebx,ebx 将ebx的值清0.
(compare):比较指令,实际上时根据第一个数减去第二个数对标志寄存器的影响决定的。http://www.oicqzone.com/pc/2013020414917.html
(jump if equal):汇编语言中的条件转移指令,结果为0(不相等)则转移。
汇编语言中,串操作指令lodsd/lodsw是块读出指令,其具体操作是把SI指向的存储单元读入累加器。Lodsb是读入al中,lodsw是读入ax中,然后si自动增加或减少1或2位。当标志位df=0时,则si自动增加,df=1时,则si自动减少。
Stosb/STOSW也是块写入指令,其具体操作是把累加器的内容写入到存储单元中,其中STOSB是从AL中读入,STOSW是从AX读入,然后si自动增加或减少1或2位,当方向DF=0时,则SI自动增加,当SI=1时,则SI自动减少。
,汇编的传送指令之一,与它相关的还有PUSHA,POPA/POPAD,他们配合使用用于8个16位/32位通用寄存器之间的数据传送。PUSHAD指令压入32位寄存器,其入栈顺序是EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI.(相当于多个push)
(convent double to quad):这个指令将EAX(32位)变为EDX:EAX形式(64位),这样一变之后EDX就充当了符号位,如果其为正数,edx 置 0(00000000);如果其为负数,edx 置 -1(FFFFFFFF) ;这样,指令后的 edx:eax 形成的一个 qword 数,就和原来的 eax 这么个 dword 的值相等;这个指令通常用在应付后续的 div dword 指令上。(本来EAX中既可以是正数,也可以是负数)(很久前 指令集规定除数必须是被除数的一半长,就一直沿用下来。IDIV有符号除法指令, 除数是32位,那么被除数需要64位,然后就用EDX来扩展EAX的符号位,这样既不改变EAX的值 又扩展成64位)
,带符号位传送。
,jump if zero。
,循环右移,并补位。
与pushad互逆,依次弹出EDI,ESI,EBP,ESP,EBX,EDX,EAX.
一开始没学这个的时候,我认为内存分为好多段,段里再细分地址。其实,内存里并没有什么分区分段,这里的 物理地址=段地址+偏移地址 实际上是因为CPU的结构位数小于地址总线的位数,CPU为了能指示出所有的内存地址而弄出的一种表示方法。
(例如在8086CPU中,地址总线为20位,可以寻1M地址,但CPU的位数只有16位)
可以将这里的地址比喻为梯子,一个梯子只有16米长,到达不了20米高的地方,但是我们可以在这个梯子的基础上再加一个16米的梯子,这样我们就可以到达20米高的地方了。
在xp及以下的系统中,可以用debug来查看以及更改寄存器和内存的数据。
R,查看,改变寄存器的内容
D,查看内存的内容
E,改写内存的内容
T,执行一条机器语句(执行CS:IP指向的内存中的指令)
我们在看0day时知道,指令即数据,数据即指令,那么是什么将数据和指令分开呢?CPU将CS:IP指向的内存中的数据看做指令,如果一条指令被执行,那么它所在的内存一定被CS:IP指向过。与此相对应的,CS:IP没有指向的内存里存的就是数据了。
CPU中有编译器,先将IP寄存器指向的机器码编译为汇编代码,判断其是否为一个完整的汇编语句,若是,则将这条语句的信息反馈给寄存器,IP寄存器地址变化;若不是,则继续读取下一内存的机器码编译,判断,直至找到完整的汇编代码。
http://jpkc.nwpu.edu.cn/jp2007/05/dzjc/text/chapter2/section2/text1r.htm
段寄存器是用于段寻址用的,而程序之间有段保护。这个段保护使得一个程序的崩溃不会影响到其他程序。
又由于段寄存器是用来当前正在运行的进程获得它的段寻址用的,所以一定不能乱变。
CS,DS,SS等所有和段相关的寄存器都不能不能用来计算。
本文出自 “天下皆白,哼” 博客,请务必保留此出处http://xiaoqin00.blog.51cto.com/10468367/1719127
原文地址:http://xiaoqin00.blog.51cto.com/10468367/1719127