32位80x86汇编语言ptr指令学习笔记
学习汇编语言的心得体会
此刻简单总结汇编语言指令的分类:一、数据传送指令;二、标志位操作指令;3 、算术运算指令;4、逻辑运算指令;五、移位运算指令;六、位操作指令;7、
比较运算指令;八、循环指令;九、转移指令;10、条件设置字节指令;1一、字符串操作指令;1二、BCD码运算调整指令;13、处置器指令。
在编写汇编程序时,应该注意专门容易显现的错误,例如在编写数据传送指令时,目的操作数和源操作数的类型必然要匹配,CS不能作为目的操作数,offset后只能跟简单地址符号,等等。
汇编语言的寻址方式有直接寻址,寄放器寻址,基址变址寻址,相对基址变址寻址等等,把握这些都是编写汇编程序很重要的环节。
汇编语言中的程序结构,子程序等知识也会帮忙咱们编写出一个加倍完善的汇编程序。另外,咱们还应该把握DOS系统功能挪用,宏汇编等知识。那个地址要对子程序和宏汇编加以区分,我的明白得是:子程序是挪用,而宏是替换,比如一个MAX宏,所有显现MAX的地址,都用宏代码代替。
其中方括号中的内容为可选项。指令助记符决定了指令的功能,对应一条二进制编码的机械指令。指令的操作数个数由该指令确信,能够没有操作数,也能够有一个或多个操作数,大多数指令要显示写出来,还有些操作数是隐含的。当指令包括操作数的时候,书写时必需遵守:一、指令助记符和操作数之间有分隔符,比如几个空格;二、若是含有多个操作数,操作数之间用逗号分隔。
X86汇编语言学习
X86汇编语言学习手记
X86汇编语言学习手记(1)
1. 编译环境
OS: Solaris 9 X86
Compiler: gcc 3.3.2
Linker: Solaris Link Editors 5.x
Debug Tool: mdb
Editor: vi
注:关于编译环境的安装和设置,可以参考文章:Solaris 上的开发环境安装及设置。
mdb是Solaris提供的kernel debug工具,这里用它做反汇编和汇编语言调试工具。
如果在Linux平台可以用gdb进行反汇编和调试。
2. 最简C代码分析
为简化问题,来分析一下最简的c代码生成的汇编代码:
# vi test1.c
int main()
{
return 0;
}
编译该程序,产生二进制文件:
# gcc test1.c -o test1
# file test1
test1: ELF 32-bit LSB executable 80386 Version 1, dynamically linked, not stripped
test1是一个ELF格式32位小端(Little Endian)的可执行文件,动态链接并且符号表没有去除。
这正是Unix/Linux平台典型的可执行文件格式。
用mdb反汇编可以观察生成的汇编代码:
# mdb test1
Loading modules: [ libc.so.1 ]
> main::dis ; 反汇编main函数,mdb的命令一般格式为<地址>::dis
main: pushl %ebp ; ebp寄存器内容压栈,即保存main函数的上级调用函数的栈基地址
汇编ptr指令
汇编ptr指令
1. 什么是汇编ptr指令
在计算机科学中,汇编ptr指令是一种命令,用于处理指针(pointer)。指针是一种数据类型,用于存储内存地址。通过指针,我们可以直接访问内存中的数据,而不需要通过变量名。
汇编ptr指令允许程序员直接操作指针,并对指针进行加载、存储和操作。这使得程序员可以更加灵活地编写汇编语言程序,从而更好地控制内存和数据。
2. 汇编ptr指令的语法
汇编ptr指令的语法可以根据具体的汇编语言而有所不同,下面以x86汇编语言为例来介绍常见的汇编ptr指令的语法:
2.1 加载指令(Load)
mov [destination], [source]
加载指令用于将指针指向的内存地址中的值加载到寄存器或其他指针中。[destination]表示目标寄存器或指针,[source]表示源地址指针。
例如,以下指令将将[ebp+8]处的值加载到eax寄存器中:
mov eax, [ebp+8]
2.2 存储指令(Store)
mov [destination], [source]
存储指令用于将寄存器或其他指针中的值存储到指针指向的内存地址。
例如,以下指令将将eax寄存器中的值存储到[ebp+8]处:
mov [ebp+8], eax
2.3 指针操作指令
汇编ptr指令还支持进行指针运算和指针地址的计算。具体的语法可以根据不同的汇编语言而有所不同。
例如,以下指令将eax寄存器的值乘以4,并将结果存储到edx寄存器中:
lea edx, [eax*4]
3. 汇编ptr指令的应用示例
为了更好地理解汇编ptr指令的应用,下面给出一个示例。
x86汇编指令详解x86汇编指令详解
x86汇编指令详解
x86汇编指令详解
指令包括三部分:数据传送指令、运算指令、跳转指令。
Intel寄存器包括:通用寄存器AX,BX,CX,DX;通用寄存器由分为8位、16位、32位,其中AL、AH是AX高、低8位寄存器,BL、BH是BX的高、低8位寄存器,CL、CH是CX的高、底8位寄存器,DL、DH是DX的高、低8位寄存器;段寄存器DS,ES,SS,CS,FS,GS;堆栈指针SP,程序计数器IP。
一、传送指令
在存贮器和寄存器和输入输出端口之间传送数据。
1. 通用数据传送指令(R代表寄存器,M代表存储器,I代表立即数)
MOV 第一操作数,第二操作数;
功能:把第二操作数传给第一操作数,第一操作数必须是寄存器或存储单元,第二操作数可以是寄存器、存储器,也可以是立即数。
如:MOV AX,CX; CX——〉AX
MOV BX,WORD;WORD——〉BX
MOV AX, 10H;10H——〉AX
第一操作数可以换成存储器,如word。
各种传送指令
源操作数是寄存器
MOV CH, AL
MOV BP, SP
MOV ECX, EBX
MOV DS, AX
MOV [BX], CH
源操作数是存储单元
MOV AL, [100H]
MOV BX, ES:[DI]
MOV EDX, [BX]
MOV BX, VARW
其中:VARW是字类型内存变
量(下同)。
源操作数是立即数
MOV AL, 89H
MOV BX, -100H
MOV EDX, 12345678H
MOV VARW, 200H
MOV [BX], 2345H
PUSH 操作数;把操作数压入堆栈,堆栈指针SP+1;
汇编语言中PTR的含义及作用
汇编语言中PTR的含义及作用在汇编语言中,PTR是一个非常重要的指令。PTR是Pointer(指针)的缩写,用于表示和操作内存地址。它可以帮助程序员直接访问和操
纵内存中的数据,提供了更高级别的内存操作功能。
一、PTR指令的含义
PTR指令用于设置和操作指针寄存器。指针寄存器是用于存储内存
地址的寄存器,它们可以指向内存中的某个特定位置,从而使程序能
够读取或写入该内存位置的数据。在汇编语言中,常用的指针寄存器
有DS(数据段寄存器)、ES(目标段寄存器)、SS(堆栈段寄存器)等。
二、PTR指令的作用
1. 读取和写入内存数据:PTR指令允许程序员通过指针寄存器直接
读取或写入内存数据。通过设置PTR指令的操作数为目标内存地址,
程序可以将数据加载到寄存器中,或者将寄存器中的数据存储到目标
内存地址中。
示例:
```assembly
MOV AX, PTR[BP+DI] ; 将DS:BP+DI地址处的数据加载到AX
寄存器中
MOV PTR[SI], BX ; 将BX寄存器的值存储到ES:SI地址处
```
2. 数据传送和复制:PTR指令可以用于在不同段之间进行数据传送
和复制操作。通过设置指针寄存器的值为源和目标段的基地址,程序
可以将数据从一个段复制到另一个段,实现不同段之间的数据传递。
示例:
```assembly
MOV CX, 200 ; 设置传送数据的长度
MOV DS, SRC_SEG ; 设置源段基地址
MOV ES, DEST_SEG ; 设置目标段基地址
MOV PTR[DI], ES:[SI] ; 复制ES:SI地址处的数据到ES:DI地址处
汇编学习笔记(15)-80386从16位32位
汇编学习笔记(15)-80386从16位32位
简述
80386相⽐于8086 地址线从20位扩展为32位,这意味着80386可以最多访问4G的内存,同时所有的寄存器都扩展为32位寄存
器,80386扩展了原来的寄存器,增加了⼀些新的指令,并增加了新的寄存器
80386的寄存器主要分如下⼏类:通⽤寄存器,段寄存器,指令寄存器,标志位寄存器,系统地址寄存器,控制寄存器,测试寄存器,调试寄存器。
80386的指令集也⼤多集成8086的指令集,只是将其扩充为32位寄存器⽽已。
寄存器
通⽤寄存器
通⽤寄存器是在8086的8个通⽤寄存器(AX,BX,CX,DX,BP,SP,SI,DI)的基础上将其扩展了32位寄存器,名称为在原先的名字前⾯加了个E,分别为EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI
原先的16位和8位寄存器即 AX, AL ,AH等都还是可以使⽤的,同时AX 是EAX的低16位,类似于 AX和AL的关系,EAX的⾼16位⽆法单独使⽤。
段寄存器
原先的段寄存器保持不变还是16位,同时增加了FS 和 GS两个新的段寄存器(这两寄存器的全称是啥没查到)
指针寄存器
扩展为32位,改名为EIP,IP仍然有效,是EIP的低16位
标记寄存器
标志寄存器也扩展为32位,并层架如下四个标志位
IO 特权(IOPL): 当执⾏IO指令的时候需要IO的特权级⼩于等于此标志位,占2位
嵌套任务标志(NT): ⽤来指⽰中断返回指令 IRET的⼯作⽅式
重启标志(RF): 与故障和调试有关
《80x86汇编语言程序设计》教案及答案
《汇编语言程序设计》教案
附:习题参考答案
《IBM-PC汇编语言程序设计》
(第2版)
沈美明、温冬婵编著
教案编写时间:20XX年8月18日
前言
1.汇编语言是计算机能提供给用户的最快而又最有效的语言,也是能够利用计算机所有硬件特性并能直接控制硬件的唯一语言。
2.汇编语言程序设计是高等院校电子计算机硬、软件及应用专业学生必修的核心课程之一。它不仅是计算机原理、操作系统等其它核心课程的必要先修课,而且对于训练学生掌握程序设计技术、熟悉上机操作和程序调试技术都有重要作用。
3.本教材共有十一章,其内容安排如下:
(1).第一、二章为汇编语言所用的基础知识。
(2).第三章详细介绍80x86系列CPU的指令系统和寻址方式。
(3).第四章介绍伪操作、汇编语言程序格式及汇编语言的上机过程。
(4).第五、六章说明循环、分支、子程序结构和程序设计的基本方法。
(5).第七章说明宏汇编、重复汇编及条件汇编的设计方法。
(6).第八章叙述输入/输出程序设计方法,重点说明中断原理、中断过程及中断程序设计方式。
(7).第九章说明BIOS和DOS系统功能调用的使用方法。
(8).第十~十一章分别说明图形显示、发声及磁盘文件存储的程序设计方法,同时提供各种程序设计
方法和程序实例。
附:教学参考书
1.沈美明、温冬婵编著,IBM–PC汇编语言程序设计(第2版),清华大学出版社,20XX年(教材)
2.沈美明、温冬婵编著,IBM–PC汇编语言程序设计,清华大学出版社,1991年
3.沈美明、温冬婵编著,IBM–PC汇编语言程序设计—例题习题集,清华大学出版社,1991年6月
80x86微机原理参考答案
80x86微机原理参考答案
第一章计算机基础(P32)
1-1电子管,晶体管,中小规模集成电路、大规模、超大规模集成电路。
1-2把CPU和一组称为寄存器(Registers)的特殊存储器集成在一片大规模集成电路或超大规模集成电路封装之中,这个器件才被称为微处理器。以微处理器为核心,配上由大规模集成电路制作的只读存储器(ROM)、读写存储器(RAM)、输入/输出、接口电路及系统总线等所组成的计算机,称为微型计算机。微型计算机系统是微型计算机配置相应的系统软件,应用软件及外部设备等.
1-3写出下列机器数的真值:
(1)01101110 (2)10001101
(3)01011001 (4)11001110
答案:
(1)+110 (2)-13(原码) -114(反码)-115(补码)(3)+89 (4)-78(原码)-49(反码)-50(补码)
1-4写出下列二进制数的原码、反码和补码(设字长为8位):(1)+010111 (2)+101011
(3)-101000 (4)-111111
答案:
(1)[x]原=00010111 [x]反= 00010111 [x]补= 00010111
(2)[x]原=00101011 [x]反= 00101011 [x]补= 00101011
(3)[x]原=10101000 [x]反= 11010111 [x]补= 11011000
(4)[x]原=10111111 [x]反= 11000000 [x]补=11000001
1-5 当下列各二进制数分别代表原码,反码,和补码时,其等效的十进制数值为多少?
最新汇编语言中ptr的含义及作用
汇编语言中PTR的含义及作用
ptr -- pointer (指针)缩写。
汇编里面 ptr 是规定的字 (保留字)。
mov ax,bx ;是把BX寄存器“里”的值赋予AX,由于二者都是word型,不用word
mov ax,word ptr [bx];是把内存地址等于“BX寄存器的值”的地方所存放的数据,赋予ax。由于只是给出一个内存地址,不知道希望赋予ax的,是byte还是word,所以需要用word明确指出!
所以,当两个操作数的宽度不一样时,就要用到ptr。
(可以理解为,ptr是临时的类型转换,相当于C语言中的强制类型转换)
也就是说
*p 用汇编表示就是:dword ptr [p]
*p是取p所指内存地址处的值。
(1)通过寄存器名指明要处理的数据的尺寸。(既有寄存器,可以不用ptr来限制了,系统会自动分析的)
例如:
下面的指令中,寄存器指明了指令进行的是字操作:
mov ax,1
mov bx,ds:[0] 这个的意思是段内的偏移地址是0,段地址是DS。详情请看本人其他日记
mov ds,ax
mov ds:[0],ax
inc ax
add ax,1000
下面的指令中,寄存器指明了指令进行的是字节操作(因为是al):
mov al,1
mov al,bl
mov al,ds:[0]
mov ds:[0],al
inc al
add al,100
(2)在没有寄存器名存在的情况下,既都是在内存,得用操作符 X ptr 指明内存单元的长度,X在汇编指令中可以为byte,word或者DWORD。要不然内存是片连续的区域,操作就乱了。
汇编ptr指令
汇编ptr指令
一、简介
汇编语言是一种低级的计算机语言,它使用符号化的指令来操作计算
机硬件。指令是汇编语言中最基本的单元,而ptr指令则是其中一个
重要的指令之一。
二、ptr指令的作用
ptr指令可以将一个16位或32位的内存地址加载到一个寄存器中,
或者将一个寄存器中的值写入到内存地址中。它主要用于访问内存中
的数据,包括读取和写入。
三、ptr指令的语法
在汇编语言中,ptr指令有两种不同的语法形式:
1. ptr type [address]
这种形式将一个内存地址加载到一个寄存器中,并且需要明确指定
数据类型(type)。
2. ptr [address]
这种形式将一个内存地址加载到默认寄存器(DS:BX或DS:EBX)中,并且不需要明确指定数据类型。
四、ptr指令示例
以下是一些常见的ptr指令示例:
1. 将一个16位内存地址加载到AX寄存器中:
mov ax, ptr [0x1234]
2. 将一个32位内存地址加载到EAX寄存器中:
mov eax, ptr [0x12345678]
3. 将AX寄存器中的值写入到0x5678处:
mov ptr [0x5678], ax
4. 将EAX寄存器中的值写入到0x12345678处:
mov ptr [0x12345678], eax
五、ptr指令的注意事项
在使用ptr指令时需要注意以下几点:
1. 必须明确指定数据类型,否则会导致数据读取错误。
2. 内存地址必须是有效的,否则会导致程序崩溃。
3. 内存地址必须按照正确的字节顺序进行读取和写入,否则会导致数据错误。
【免费下载】8086汇编语言学习笔记
s:add ax,ax,执行 ax=ax+1
add bx,bx,执行 bx=bx+1
loop s,执行 cx=cx-1,cx==0,则往下,cx!=0,则转到 s 标记的内存地址中继
续执行
3、在汇编程序中,数据不能由字母开头,故
mov ax,FFFFH 不合法,要改为 mov ax,0FFFFH
中,并把 sp 的值改为 sp-2(这是在 8086 当中,因为 ax 是 16 位寄存器,而内存单元
为 8 位,因此一个寄存器的值要用两个内存
单元来存放)
5、pop,出栈,比如 pop ax,将 ss:sp 指向的内存的值送入 ax 中,并把 sp 的值
改为 sp+2
pop [0],将 ss:sp 内存中的数据弹出到 ds:0 内存中,注意 pop 操作是字为单位的
code segment
start: ....
mov ax,4c00H
int 21H
code ends
end
这几行是基本的,不然程序无法编译运行。
1、程序完后要输入
mov ax,4c00H
int 21H
帮助程序返回。
2、利用 loop 实现循环
mov cx,11,将 cx 寄存器值置为 11
汇编语言讲义第三章 80x86的寻址方式
…
的内容左移4位后,加上指令给定的16位地址偏移量。
• 默认段为数据段。
CS
例7 MOV AX,[2000H] ;((DS)×10H+Biblioteka Baidu000H)→AX
A1H 00H 20H
…
执行前:(DS)= 3000H
执行后:(AX)= 5050H
DS
20020H
89H 37H
… … … …
AX
00 00H
例13 MOV 6[BP],BX
; (BX)→(SS)×10H+(BP)+6
…
执行前:(BX)= 4000H,(BP)= 30H,
(SS)= 2000H,(20036H)= 0000H 执行后:(BX)= 4000H,(BP)= 30H, (SS)= 2000H,(20036H)= 4000H
结构的需要,这个段内偏移地址可以由
几个部分组成,把它称为有效地址EA。
1、立即寻址方式:n
• 所提供的操作数(立即数)紧跟在操作码的后面,与操作码一起放在指令代
码段中。
• 立即数可以是8位数或16位数。 • 只能用于源操作数字段,不能用于目的操作数字段,经常用于给寄存器赋初
值。 例1 MOV AL,18 ; 18→AL 以下为错误的指令:
汇编语言 第3章1 80x86的指令系统和寻址方式
立即数寻址指令
MOV AL,05H ;AL←05H
MOV AX,0102H ;AX←0102H
立即寻址
3.1.3 寄存器寻址方式
操作数存放在CPU的内部寄存器reg中,
可Baidu Nhomakorabea是:
– 8位寄存器r8:
AH、AL、BH、BL、CH、CL、DH、DL
– 16位寄存器r16:
AX、BX、CX、DX、SI、DI、BP、SP
– 4个段寄存器seg:
CS、DS、SS、ES
寄存器寻址指令
MOV AX,1234H MOV BX,AX ;AX←1234H ;BX←AX
寄存器寻址
3.1.4 存储器寻址方式
指令中给出操作数的主存地址信息(偏移
地址,称之为有效地址EA),而段地址在 默认的或用段超越前缀指定的段寄存器中
8086设计了多种存储器寻址方式
基址变址
(5)相对基址变址寻址方式
有效地址是基址寄存器(BX/BP)、变址寄存
器(SI/DI)与一个8位或16位位移量之和:
有效地址=BX/BP+SI/DI+8/16位位移量
段地址对应BX基址寄存器默认是DS,对应BP
基址寄存器默认是SS;可用段超越前缀改变 MOV AX,[BX+SI+06H]; mov ax, mask[bx][si]
32位汇编入门知识
32位汇编入门知识
简介:
汇编语言是一种低级语言,它直接表达了计算机的指令和数据。本文将介绍32位汇编语言的入门知识,包括寄存器、指令、堆栈和函数调用等内容。
一、寄存器
寄存器是CPU内部用来存储和操作数据的部件,32位汇编语言中常用的寄存器有EAX、EBX、ECX、EDX等。每个寄存器都有特定的用途,例如EAX通常用于存放函数返回值,EBX通常用于存放基址。
二、指令
指令是汇编语言中最基本的单位,它表示一条计算机指令。常见的指令有MOV、ADD、SUB等。例如,MOV指令用于将数据从一个地方移动到另一个地方,ADD指令用于进行加法运算。
三、堆栈
堆栈是用于存储临时数据的一种数据结构,它具有“先进后出”的特点。在汇编语言中,堆栈用于保存函数的局部变量、函数参数和返回地址等信息。例如,PUSH指令用于将数据压入堆栈,POP指令用于将数据从堆栈中弹出。
四、函数调用
函数调用是程序中常见的操作,它用于实现代码的模块化。在汇编语言中,函数调用通常需要进行参数传递和返回值处理。例如,CALL 指令用于调用函数,RET指令用于从函数返回。
五、例子
下面通过一个简单的例子来演示32位汇编语言的使用:
```assembly
section .data
msg db 'Hello, World!', 0
section .text
global _start
_start:
; 输出字符串
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, 13
int 0x80
; 退出程序
mov eax, 1
xor ebx, ebx
《汇编语言程序设计》第十五章:32位80X86汇编
www.tup.com.cn
南开大学 朱耀庭
4. 寄存器
图15-4 80386的段寄存器
指令仅可访问部 分 CS DS SS ES FS GS 16位 段选择器 12位 段属性 32位 段基址 20位 段长度 64位描述符寄存器(指令不可访问)
www.tup.com.cn
南开大学 朱耀庭
4. 寄存器
这里所指的386CPU是指纯粹32位的CPU,它对内、对外 的数据总线都是32位,地址总线有32根,所以可直接寻址 的空间为232B=4096MB=4GB。和8086CPU相比, 80386有以下4个主要特点: (1) 支持多任务。80386能同时运行两个或两个以上的程序。 用一条机器指令就可以进行任务的切换。当然,在每一瞬 间,CPU都只能由一个程序占有,这一特点不变。只是 80386的结构决定并且保证了这种多任务切换的顺利实施。 (2) 支持存储器的段式管理和页式管理,为操作系统实现 虚拟存储系统提供了条件。
汇编语言程序设计
-------朱耀庭 ---------朱耀庭
www.tup.com.cn
第15章 32位80X86汇编
实模式下汇编语言程序设计的主体思想和方法是重要的, 这种思想和方法可以应用到任意一种不同CPU结构的计算 机上。 要开发相应CPU的汇编语言程序,只要有该CPU的逻辑结 构、寻址方式、机器指令集说明书和配套的汇编程序就应 该能够胜任。 因此本章不再就程序设计的基本思想和方法进行介绍,而 将主要精力放在32位的80X86保护模式汇编与之前所学的 “实模式”汇编之间的主要区别之上。 希 望 同 学 们 通 过 本 章 的 学 习 了 解 Win32 汇 编 , 了 解 在 Windows环境下如何调试和运行一个Win32汇编程序。
80x86汇编指令详解
80x86汇编指令详解(上)
2008年01月15日星期二 15:05
80x86指令系统,指令按功能可分为以下七个部分。
(1) 数据传送指令。
(2) 算术运算指令。
(3) 逻辑运算指令。
(4) 串操作指令。
(5) 控制转移指令。
(6) 处理器控制指令。
(7) 保护方式指令。
3.3.1数据传送指令
数据传送指令包括:通用数据传送指令、地址传送指令、标志寄存器传送指令、符号扩展指令、扩展传送指令等。
一、通用数据传送指令
1 传送指令
传送指令是使用最频繁的指令,格式:MOV DEST,SRC
功能:把一个字节,字或双字从源操作数SRC传送至目的操作数DEST。
传送指令允许的数据流方向见图3 11。
图 3.11 传送指令数据流
由上图可知,数据允许流动方向为:通用寄存器之间、通用寄存器和存储器之间、通用寄存器和段寄存器之间、段寄存器和存储器之间,另外还允许立即数传送至通用寄存器或存储器。但在上述传送过程中,段寄存器CS的值不能用传送指令改变。
例 3.12CPU内部寄存器之间的数据传送。
MOV AL,DH ;AL←DH(8位)
MOV DS,AX ;DS←AX(16位)
MOV EAX,ESI ;EAX←ESI(32位)
例 3.13CPU内部寄存器和存储器之间的数据传送。
MOV [BX],AX ;间接寻址(16位)
MOV EAX,[EBX+ESI] ;基址变址寻址(32位)
MOV AL,BLOCK ;BLOCK为变量名,直接寻址(8位)
例 3.14立即数送通用寄存器、存储器。
MOV EAX,12345678H ;EAX←12345678H(32位)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
阅读反汇编后的汇编程序挺麻烦,尤其是在c语言程序的子函数参数中有数组参数,同时当子函数里有循环操作时,反汇编后的代码中频繁出现ptr指令操作。该指令的用法十分灵活,有时候读入(或写入)的是某内存地址,有时候读入(写入)的是某内存地址中存储的值,初学时总感觉很迷惑,分不清什么时候读内存地址,什么时候读内存地址中值,参考相关文献和书籍后作如下总结。
例如一段简单的C语言程序:
int mywork(int a[9], int b[9], int c[9])
{
int i;
for ( i=0; i<9; i++)
c[i] =a[i] +b[i];
}
这段代码debug版反汇编后代码很简单,但是里面有许多小细节值得推敲。
int mywork(int a[9], int b[9], int c[9]) ;原c代码
… … ;这里为开始调用函数时当前寄存器数据保存
for ( i = 0 ; i < 9 ; i ++)
mov dword ptr [i], 0;这里为i初始化,值为0
jmp mywork+xx1h ;进入循环体内部
mov eax, dword ptr [i];
add eax, 1
mov dword ptr [i], eax
mywork+xx1h:cmp dword ptr [i], 9
jge mywork+xx2h ;如果i等于或大于9,跳出循环
c[i] =a[i] +b[i];
mov eax, dowrd ptr [i] ;读入参数i
mov ecx, dword ptr [a] ;这里是读入参数数组a的首地址
mov edx, dword ptr [b] ;这里是读入参数数组b的首地址
mov eax, dword ptr [ecx + eax*4] ;读入a
add eax, dword ptr [edx +eax*4] ; eax = a[i]+b[i]
mov edi, dword ptr [c] ;这里是读入参数数组c的首地址
mov dword ptr [edi+ eax*4], eax ;这里保存计算结果,c[i]= a[i]+b[i]
inc eax
jmp mywork+xx1h
mywork+xx2h: … … ;一些数据恢复操作,主要是出栈等
ret
文中用红色标记处两处涉及ptr指令的地方。
第一处为mov eax, dword ptr [i]
本条mov指令的结果是将变量i的值读入到eax寄存器中,至于从i变量存储地址处读取几个字节,由dword修饰符指定(4个字节)。
第二处为mov ecx, dword ptr [a]
这里表示将参数数组a的首地址读入到ecx寄存器中。
同样两个mov 寄存器, dword ptr [变量]操作,为何第一个寄存器eax读入数值,而第二个ecx寄存器读入的为地址呢?
ptr指令会指定并修改当前已分配内存地址的标记,因为i为c语言子函数mywork中定义的int变量,而非外部传入的参数,从而在执行子函数的汇编程序中变量i的值就是保存在dword ptr [i]返回的内存地址中,占用4个字节,所以mov eax, dword ptr [i]指令将源操作数指定的地址中数据(即int变量i的值)读入到eax寄存器中;而第二处中由于数组a的首地址是作为参数传送到mywork中的,在调用mywork前,3个数组参数a、b、c的首地址依次按照c、b、a的顺序被push入栈,并且传递给子函数,因此dword ptr [a]表示数组a作为参数传递给子函数的值,即其起始首地址,并非a[0]的值,从而mov ecx, dword ptr [a]后的结果是把数组a的首地址保存在了ecx中,而非a[0]的值
第一次发读书笔记,如果写的有误请大家指正:)
苏清华,2011.6.28
联系邮箱:suqinghua4587@