首页
社区
课程
招聘
[旧帖] [原创]我对汇编的一点理解,希望对初学的有所帮助 0.00雪花
发表于: 2010-10-16 20:06 1137

[旧帖] [原创]我对汇编的一点理解,希望对初学的有所帮助 0.00雪花

2010-10-16 20:06
1137
很多人推荐学习汇编用王爽的书,一直不解,国内很多书不都是抄袭来抄袭去么?自己看了以后才有所感悟。原来王爽是计算机科学教育家,不像很多 大家 虽自己会,但是表达教书不咋样啊。而且书的章节编排,书中问题的提出都很有启发性,在此强烈推荐,绝不是广告~~在此小结一下留作纪念。
一、基础知识。
     1、最有启发的是8086CPU给出物理地址的方法即:物理地址=段地址*16+偏移地址,为什么计算机如此计算物理地址呢?书中解释道:8086CPU为16位结构,为了拓展其寻址能力,用两个16位地址形成20位物理地址。因此就稍微麻烦一点,采用了以上的计算方法,而不是直接进行存取。
二、寄存器  
   2、段寄存器:CS IP。 CS 对应上面的段地址,IP对应上面的偏移地址。任意时刻,CPU将CS:IP指向的内容当作指令执行。对于修改CS,IP,我们可以直接MOV指令修改CS的值,但是却不能这样修改IP的值,一般使用如下语法修改:jmp 段地址:偏移地址 如:jmp 2AE3:3,执行后CS=2AE3H , IP=0003H,CPU将从2AE33H处读取指令。也可以直接 jmp ax ,表示CS不修改,而将IP的值进行修改为ax。
     3、书中还提到了用CMD中的命令debug进行调试程序,感觉和OD提供的很多调试方法很像。具体不知道有没有人将CMD中的debug作为调试工具进行软件调试。
三、寄存器(内存访问)
     4、8086CPU用DS寄存器存放要访问数据的段地址。
         mov ax,1000H
              mov ds,bx
              mov al,[0]
              表示为:将10000H(1000:0)中的数据读到al中,al为ax寄存器中的低8位。[...]表示内存单元,里面的数值0表示其偏移地址。注意:8086CPU不支持将数据直接送入段寄存器的操作,因此mov ds,1000H 是非法的,所以就麻烦一点先将段地址保存到ax中,在放入ds中。
       5、针对上面的例子mov al,[0],这个指令到底将多少字节放入al中呢,其实这取决于al的大小,al为一个字节因此放入一个字节,[0]仅仅代表的是取数据的开始地址,并不包含取多少个字节。这也就好比喝啤酒,有人搬来了一扎啤酒,可是自己却只能喝2瓶,于是我只接受两瓶,别的也就不要了。
        6、mov ax,[2] 这个表示将第三个内存单元中的数据放入ax中每一个内存单元代表的是一个字节,因此mov ax,[0] 与mov ax,[2] 相差两个内存单元,即二者的段地址距离为2个字节。ff ff ff ff 如果以上的数据为在段地址为0处的数据, 那么mov ax,[0]将第一个ff 与第二个 ff放入ax 中,而mov ax,[2] 则将第三个ff 和第四个ff放入到ax 中。
         7、CPU提供的堆栈机制。其实联系书后面提到的内容,堆栈存在的意义就是能方便简洁的记录临时数据。对于栈的操作是以字为单位的,在此有必要提一下字,字节,比特的关系。1DWORD(双字)=2*WORD(字)     1WORD=2*BYTE(字节) 1BYTE=8*bit 而bit只有两种取法1或者0,对应于二进制则为:1byte=00000000 八位二进制 8位二进制的取值最大值为 2^8=256 而256=16*16 即一个8位二进制对应于两位的十六进制,于是1byte代表两位的十六进制。因此所如果说内存中存有1f 2f 让我们从[0]处取一个字节,我们则取1f 即取两位16进制则满足要求。以上的东西一直感觉有点乱,趁此刚好自己再复习复习。
         8、栈使用SS:SP SS寄存器代表段地址,SP代表偏移地址,任意时刻SS:SP指向栈顶元素。push ax 执行时具体执行两步:(1)SP=SP-2 (2)将ax中的内容送入 SS:SP指向的内存单元 为什么要先进行SP=SP-2呢,因为如果先将ax数据放入SS:SP,那么原来的内容就会被覆盖了。pop ax则相反 (1)将SS:SP指向的内存单元送入ax 中(2)SP=SP+2 如果顺序颠倒了,则将会把别处的数据放入到ax中。仔细一想为什么 SP=SP-2 或者是SP=SP+2呢 为什么不是SP=SP+1呢,理由很简单。上面说到栈的操作以字为单位而我们每一个内存单元为1个字节,因此SP=SP+2表示 后推2个字节 即后推一个字 于是就符合了栈以字为操作单位的要求。
          9、书中还提到了栈顶超界的问题,这个好像在漏洞提取运用上有具体应用。Oday上面看目录好像有介绍,网购的看雪的0day也即将到手,在此磨拳霍霍。 在此深感汇编作为一门基础的重要性。
四、第一个程序
          10、第一个程序具体表述了一个汇编程序的编写过程,感觉好像跟逆向破解没什么关系,若有人指点其间关系,感激不尽。
五、[BX]和loop指令
           11loop指令执行时进行的操作。(1) (cx)=(cx)-1 (2) 判断cx中的值,不为0则转至标号处执行,如果为0则向下执行。cx中存放循环次数。注意:loop指令中的标号地址要在前面。 额外注意:在汇编程序中,数据不能以字母开头,为什么是这样,若有人赐教,在此感激不尽。
            12、段前缀:物理地址默认以DS为段地址,实际上我们也可以用别的作为段地址。如:mov ax,ss:[bx]
六、包含多个段的程序。
            13、代码段,数据段,栈段完全是我们的安排,CPU并不知道他们,标号代表偏移地址。
六、更灵活的定位内存地址方法。
            14、记得以前在看别人破解教程时说:看到or al,00100000B 就知道是将字母变为小写字母。为什么是这样的呢,因为ascii码中,大写字母+20H=小写字母,而20H正好是00100000B,对一个字母进行或运算,则将其转变为小写字母。
            15、SI和DI。si和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用。
七、数据处理的两个基本问题
            16、8086CPU中,只有bx,si,di,bp这四个寄存器可以用在[...]中进行内存单元的寻址。但是又不能写成这样mov ax,[bx+bp],为什么不能如此,可能涉及到一些很深入的问题。在此我只是记住,bx,bp中取一个寄存器,si,di中取一个寄存器,然后将二者合并组合则得到合法的表示方法。
             17、指令要处理的数据有多长。mov word ptr ds:[0],1。用word ptr或byte ptr显性指明所要访问的内存单元的长度是很有必要的,否则,CPU不知道所要访问的单元是字单元,还是字节单元。实际应用中有这么一句 mov byte ptr [bx].10h[si],'V' 实际等效于EA=bx+10+idata SA=ds。这种多样的表示方法为什么不直接使用一种来表示岂不是很简单,我理解其可能是为了与高级语言更好的融合。
             18、div指令。除数为8位,则被除数为16位,默认放在AX中,商放在AL中,AH中放入余数;如果除数为16位,则被除数为32位,默认DX存放高16位,AX存放低16位,商放入AX中,余数放入DX中。
              19、dup。使用格式:db或者dw或者dd  重复的次数 (重复的数据)。例如db 3 dup (0,1,2) 表示定义9个字节,他们是0、1、2、0、1、2、0、1、2 相当于db 0,1,2,0,1,2,0,1,2。

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 93908
活跃值: (200199)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
2
http://bbs.pediy.com/showthread.php?t=31840

Программное обеспечение выпуска и Windows Crack Обучение
Нам-Dabei Guanyin Бодхисаттва Нам без митабха
2010-10-16 20:29
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
多谢了!学习了。
2010-10-16 21:03
0
游客
登录 | 注册 方可回帖
返回
//