“汇编语言”作为一门语言,对应于高级语言的编译器,我们需要一个“汇编器”来把汇编语言原文件汇编成机器可执行的代码。高级的汇编器如MASM, TASM等等为我们写汇编程序提供了很多类似于高级语言的特征,比如结构化、抽象等。在这样的环境中编写的汇编程序,有很大一部分是面向汇编器的伪指令,已经类同于高级语言。现在的汇编环境已经如此高级,即使全部用汇编语言来编写windows的应用程序也是可行的,但这不是汇编语言的长处。汇编语言的长处在于编写高效且需要对机器硬件精确控制的程序。而且我想这里的人学习汇编的目的多半是为了在破解时看懂反汇编代码,很少有人真的要拿汇编语言编程序吧?(汗......)

好了,言归正传。大多数汇编语言书都是面向汇编语言编程的,我的帖是面向机器和反汇编的,希望能起到相辅相成的作用。有了前面两篇的基础,汇编语言书上对大多数指令的介绍应该能够看懂、理解了。这里再讲一讲一些常见而操作比较复杂的指令。我这里讲的都是机器的硬指令,不针对任何汇编器。

无条件转移指令jmp:

这种跳转指令有三种方式:短(short),近(near)和远(far)。短是指要跳至的目标地址与当前地址前后相差不超过128字节。近是指跳转的目标地址与当前地址在用一个段内,即CS的值不变,只改变EIP的值。远指跳到另一个代码段去执行,CS/EIP都要改变。短和近在编码上有所不同,在汇编指令中一般很少显式指定,只要写 jmp 目标地址,几乎任何汇编器都会根据目标地址的距离采用适当的编码。远转移在32位系统中很少见到,原因前面已经讲过,由于有足够的线性空间,一个程序很少需要两个代码段,就连用到的系统模块也被映射到同一个地址空间。

jmp的操作数自然是目标地址,这个指令支持直接寻址和间接寻址。间接寻址又可分为寄存器间接寻址和内存间接寻址。举例如下(32位系统):

jmp 8E347D60 ;直接寻址段内跳转
jmp EBX ;寄存器间接寻址:只能段内跳转
jmp dword ptr [EBX] ;内存间接寻址,段内跳转
jmp dword ptr [00903DEC] ;同上
jmp fward ptr [00903DF0] ;内存间接寻址,段间跳转

解释:
在32位系统中,完整目标地址由16位段选择子和32位偏移量组成。因为寄存器的宽度是32位,因此寄存器间接寻址只能给出32位偏移量,所以只能是段内近转移。在内存间接寻址时,指令后面是方括号内的有效地址,在这个地址上存放跳转的目标地址。比如,在[00903DEC]处有如下数据:7C 82 59 00 A7 01 85 65 9F 01

内存字节是连续存放的,如何确定取多少作为目标地址呢?dword ptr 指明该有效地址指明的是双字,所以取
0059827C作段内跳转。反之,fward ptr 指明后面的有效地址是指向48位完全地址,所以取19F:658501A7 做远跳转。

注意:在保护模式下,如果段间转移涉及优先级的变化,则有一系列复杂的保护检查,现在可不加理会。将来等各位功力提升以后可以自己去学习。

条件转移指令jxx:只能作段内转移,且只支持直接寻址。

=========================================
调用指令CALL:

Call的寻址方式与jmp基本相同,但为了从子程序返回,该指令在跳转以前会把紧接着它的下一条指令的地址压进堆栈。如果是段内调用(目标地址是32位偏移量),则压入的也只是一个偏移量。如果是段间调用(目标地址是48位全地址),则也压入下一条指令的完全地址。同样,如果段间转移涉及优先级的变化,则有一系列复杂的保护检查。

与之对应retn/retf指令则从子程序返回。它从堆栈上取得返回地址(是call指令压进去的)并跳到该地址执行。retn取32位偏移量作段内返回,retf取48位全地址作段间返回。retn/f 还可以跟一个立即数作为操作数,该数实际上是从堆栈上传给子程序的参数的个数(以字计)返回后自动把堆栈指针esp加上指定的数*2,从而丢弃堆栈中的参数。这里具体的细节留待下一篇讲述。

虽然call和ret设计为一起工作,但它们之间没有必然的联系。就是说,如果你直接用push指令向堆栈中压入一个数,然后执行ret,他同样会把你压入的数作为返回地址,而跳到那里去执行。这种非正常的流程转移可以被用作反跟踪手段。

==========================================
中断指令INT n

在保护模式下,这个指令必定会被操作系统截获。在一般的PE程序中,这个指令已经不太见到了,而在DOS时代,中断是调用操作系统和BIOS的重要途径。现在的程序可以文质彬彬地用名字来调用windows功能,如 call user32!getwindowtexta。从程序角度看,INT指令把当前的标志寄存器先压入堆栈,然后把下一条指令的完全地址也压入堆栈,最后根据操作数n来检索“中断描述符表”,试图转移到相应的中断服务程序去执行。通常,中断服务程序都是操作系统的核心代码,必然会涉及到优先级转换和保护性检查、堆栈切换等等,细节可以看一些高级的教程。

与之相应的中断返回指令IRET做相反的操作。它从堆栈上取得返回地址,并用来设置CS:EIP,然后从堆栈中弹出标志寄存器。注意,堆栈上的标志寄存器值可能已经被中断服务程序所改变,通常是进位标志C, 用来表示功能是否正常完成。同样的,IRET也不一定非要和INT指令对应,你可以自己在堆栈上压入标志和地址,然后执行IRET来实现流程转移。实际上,多任务操作系统常用此伎俩来实现任务转换。

广义的中断是一个很大的话题,有兴趣可以去查阅系统设计的书籍。

============================================
装入全指针指令LDS,LES,LFS,LGS,LSS

这些指令有两个操作数。第一个是一个通用寄存器,第二个操作数是一个有效地址。指令从该地址取得48位全指针,将选择符装入相应的段寄存器,而将32位偏移量装入指定的通用寄存器。注意在内存中,指针的存放形式总是32位偏移量在前面,16位选择符在后面。装入指针以后,就可以用DS:[ESI]这样的形式来访问指针指向的数据了。

============================================
字符串操作指令

这里包括CMPS,SCAS,LODS,STOS,MOVS,INS和OUTS等。这些指令有一个共同的特点,就是没有显式的操作数,而由硬件规定使用DS:[ESI]指向源字符串,用ES:[EDI]指向目的字符串,用AL/AX/EAX做暂存。这是硬件规定的,所以在使用这些指令之前一定要设好相应的指针。
这里每一个指令都有3种宽度形式,如CMPSB(字节比较)、CMPSW(字比较)、CMPSD(双字比较)等。
CMPSB:比较源字符串和目标字符串的第一个字符。若相等则Z标志置1。若不等则Z标志置0。指令执行完后,ESI 和EDI都自动加1,指向源/目标串的下一个字符。如果用CMPSW,则比较一个字,ESI/EDI自动加2以指向下一个字。
如果用CMPSD,则比较一个双字,ESI/EDI自动加4以指向下一个双字。(在这一点上这些指令都一样,不再赘述)
SCAB/W/D 把AL/AX/EAX中的数值与目标串中的一个字符/字/双字比较。
LODSB/W/D 把源字符串中的一个字符/字/双字送入AL/AX/EAX
STOSB/W/D 把AL/AX/EAX中的直送入目标字符串中
MOVSB/W/D 把源字符串中的字符/字/双字复制到目标字符串
INSB/W/D 从指定的端口读入字符/字/双字到目标字符串中,端口号码由DX寄存器指定。
OUTSB/W/D 把源字符串中的字符/字/双字送到指定的端口,端口号码由DX寄存器指定。

串操作指令经常和重复前缀REP和循环指令LOOP结合使用以完成对整个字符串的操作。而REP前缀和LOOP指令都有硬件规定用ECX做循环计数器。举例:

LDS ESI,SRC_STR_PTR  
LES EDI,DST_STR_PTR  
MOV ECX,200  
REP MOVSD

上面的代码从SRC_STR拷贝200个双字到DST_STR. 细节是:REP前缀先检查ECX是否为0,若否则执行一次MOVSD,ECX自动减1,然后执行第二轮检查、执行......直到发现ECX=0便不再执行MOVSD,结束重复而执行下面的指令。

LDS ESI,SRC_STR_PTR
MOV ECX,100
LOOP1:
LODSW
.... (deal with value in AX)

LOOP LOOP1
.....

从SRC_STR处理100个字。同样,LOOP指令先判断ECX是否为零,来决定是否循环。每循环一轮ECX自动减1。

REP和LOOP 都可以加上条件,变成REPZ/REPNZ 和 LOOPZ/LOOPNZ. 这是除了ECX外,还用检查零标志Z. REPZ 和LOOPZ在Z为1时继续循环,否则退出循环,即使ECX不为0。REPNZ/LOOPNZ则相反。

汇编语言的准备知识--给初次接触汇编者 之一
[url]http://yuncx.blog.51cto.com/221873/86322[/url]
 
汇编语言的准备知识--给初次接触汇编者 之二
[url]http://yuncx.blog.51cto.com/221873/86323[/url]
 
汇编语言的准备知识--给初次接触汇编者 之三
[url]http://yuncx.blog.51cto.com/221873/86324[/url]
 
汇编语言的准备知识--给初次接触汇编者 之四
[url]http://yuncx.blog.51cto.com/221873/86325[/url]

转载于:https://blog.51cto.com/yuncx/86324

汇编语言的准备知识--给初次接触汇编者 之三相关推荐

  1. 汇编语言的准备知识--给初次接触汇编者 (1-4) 转载

    汇编语言的准备知识--给初次接触汇编者 1 在接触到游戏修改后发现需要很多的汇编知识,于是找汇编基础知识恶补,到网上搜索到一篇不错的文章,给各位想我一样的初学者一起学习! 教程: 汇编语言的准备知识- ...

  2. [转]汇编语言的准备知识--给初次接触汇编者 2

    汇编指令的操作数可以是内存中的数据, 如何让程序从内存中正确取得所需要的数据就是 对内存的寻址. INTEL 的CPU 可以工作在两种寻址模式:实模式和保护模式.前者已经过时,就不讲 了, WINDO ...

  3. [转]汇编语言的准备知识--给初次接触汇编者 3

    "汇编语言"作为一门语言,对应于高级语言的编译器,我们需要一个"汇编器"来把汇编语言 原文件汇编成机器可执行的代码.高级的汇编器如MASM, TASM 等等为我 ...

  4. 初次接触GWT,知识点总括

    初次接触GWT,知识点概括 前言 本人最近开始研究 GWT(Google Web Toolkit) ,现将个人的一点心得贴出来,希望对刚开始接触 GWT的程序员们有所帮助,也欢迎讨论,共同进步. 先说 ...

  5. 汇编语言基础入门知识

    学习汇编前你应该知道的知识   1.汇编需要什么工具和程序,到哪里下载?     目前阶段,汇编程序仅需要两个程序就够了.masm.exe,link.exe.  前者是编译程序,后者是链接程序.另外, ...

  6. 汇编语言的基础知识一

    1. 编码系统,表示系统: 地球的经纬度,时间的小时分钟秒.天上的星星:白羊座,金牛座..用图形编码,表示. 汉字,中文语言.汉字用图形对世界进行表示.用拼音字母对声波,声音的一种表示. 编码是人类对 ...

  7. SAP FIORI专题之一:初次接触fiori,用sap hana studio开发发布UI5程序

    初次接触fiori 1 准备环境 2 一个简单的CURD怎么搞 2.1 后端建service 2.1.1 SEGW进入后端主界面 2.2.2 建个表 2.2.3 引用结构创建实体 2.2.4 发布生成 ...

  8. 【汇编语言与计算机系统结构笔记05】汇编的系统结构,从C代码生产汇编代码,一个具体的、经典的数据传送指令(mov)实例与分析

    本次笔记内容: 06.寻址模式与数据传输指令等 文章目录 汇编程序员眼中的系统结构 如何从C代码生产汇编代码 如何装gcc? 汇编语言数据格式 第一条汇编指令实例 数据传送指令(mov) 语法与操作数 ...

  9. (Python入门)学习笔记一,初次接触尝试使用Python——环境搭建与配置

    (Python入门)学习笔记一,初次接触尝试使用Python 早就耳闻Python大名,搞大数据.做人工智能.整机器学习,就得了解Python.之前一直没有去了解,现在由于之前一个项目涉及到一点Pyt ...

最新文章

  1. DELL服务器结合nagios硬件监控、报警
  2. Windows 下连接mysql工具NavicatForMysql
  3. Ubuntu9.10 server 安装配置 vsftpd2.2.0 ftp服务器 并且 解决 putty 登陆 sshd 显示中文乱码
  4. 南阳oj 1的个数
  5. sharepoint 2010 记录管理 对象模型
  6. java调用jndi出错,Webshpere数据源错误:无法查找JNDI名称
  7. Python内置函数iter()语法及应用
  8. windows中如何显示/隐藏桌面图标
  9. 优化理论10----约束优化的罚函数法、外点法(Penalty method)、内点法(**Barrier Methods**)、混合惩罚函数法
  10. libcurl官方手册
  11. Word设置封面无页码,摘要罗马数字页码,正文数字页码
  12. Linux下分卷压缩与解压
  13. 綾波レイ(II)の詩
  14. 【PS】浅谈PS颜色模式-RGB模式
  15. English Word —— Day 11(discipline——editorial)
  16. 蓝桥杯 我们的征途是星辰大海 Java
  17. wlan和wfi的区别
  18. 毫米波通信与MIMO 之间的关系
  19. 基于web的大学生英语听说教学平台s
  20. 微信域名检测 实时查询域名是否被微信拦截

热门文章

  1. eclipse重置页面恢复到最初布局状态
  2. 【转】 SLIC超像素分割详解(一):简介
  3. [O365] Azure Active Directory Sync EVENT ID 906 FAILED While Purging Run History. Invalid Namespace
  4. Couldn‘t find grammar element for class javax.ws.rs.core.Response
  5. DataFrame挑选其中两列,带列名
  6. 如何计算一个神经网络在使用momentum时的hessian矩阵(论文调研)
  7. spark中的println失效问题解决
  8. ubuntu16.04 Linux+xfce4的文件夹出现两种背景颜色+文件夹中右键打开终端失灵了.
  9. NeHe OpenGL课程 网址整理
  10. 机器学习算法与Python实践之(二)k近邻(KNN)