汇编中文件的读写
汇编语言实验报告(七)班级:01540802班姓名:南征学号: 20080705信息与电子学院实验七文件的读写一、实验目的理解文件标记的概念,掌握利用文件标记读写文件的方法,学习使用文件指针读取文件。
二、实验要点磁盘文件的读写有两种方法,一种称为文件控制块;另一种方法称为文件标记,前者在读写文件时首先要设定文件控制块,知名文件所在的当前磁盘的驱动器、文件名,同时还要制定所读写的文件所处的当前块号、当前记录号、记录长度等参量,此外还需要设置磁盘传输区。
在读磁盘数据文件时,应先将磁盘上有关数据读入磁盘传输区,然后再传送至目的的内存区。
在写磁盘数据文件时,要写入磁盘文件的数据也必须先送入磁盘传输区,然后再执行写操作。
此种方法的缺点是不支持树形目录结构。
目前常用的方法是利用文件标记读写文件,无论用什么方法读写文件,都要解决以下几个问题:A)用户程序要告诉操作系统将要存取那个文件。
B)无论是从磁盘独处的数据,还是要写入磁盘的数据都必须存放在一个制定的内存缓冲区中,这个内存缓冲区叫数据传输区(DTA)。
C)在读一个磁盘文件之前,要先打开文件,然后才能将文件内容读入内存。
而在读写一个文件之前,要先建立一个新文件名,再将内存中的内容写入磁盘。
D)在存取文件之后,特别是在写入文件之后,务必将此文件关闭。
利用文件标记读写文件的主要特点是:通过建立文件、打开文件,将磁盘路径名、文件名转换为文件标记或件号,在以后读写文件的操作中均要与文件标记打交道。
在一个系统中,可同时打开多个文件,并配置相应的文件标记。
在利用文件标记读写磁盘文件是要掌握以下几个要点:1)使用建立文件、打开文件系统功能之前,都必须将DS:DX指向驱动器名、路径名、文件名和以数值零为结尾的ASCIIZ字符串的首地址。
2)对于一个新文件要用3CH系统功能调用,建立文件。
(如果不是新文件,此步骤可略)3)已存在的文件则利用3DH系统功能调用,打开此文件。
4)如果文件建立、打开成功,则CF=0,并且在AX寄存器中返回文件标记。
5)在建立、打开文件成功之后,即可对文件进行读、写操作。
如果要对文件进行读操作,则在打开文件之后,用3FH系统功能调用将文件读入数据缓冲区,调用前的入口参数是:文件标记存入BX,读入文件的字节数放入CX,数据缓冲区的起始地址存入DS:DX。
调用完毕,AX返回实际读入的字节数。
6)读入数据缓冲区的文件,可利用40H系统功能调用将文件写入指定的磁盘。
调用入口参数是:文件标记存入BX,要写入的字节数放入CX,DS:DX指向要写入数据缓冲区的首地址。
调用结束后AX返回实际写入的字节数。
如果AX<CX,则表示磁盘空间已满,但系统不提示错误信息。
7)在读、写文件完成后,要用3EH系统功能调用关闭,释放原占有的文件号,并将缓冲区的数据最终写入磁盘。
特别是对于写磁盘文件操作,在写入之后,必须要关闭文件,否则该数据文件将会丢失。
此外,特别要注意的是,在一个系统中不能同时建立两个以上的新文件。
8)在文件建立或打开后,文件指针的初始位置是指向文件首偏移为‘0’处,如果不想从文件首开始读、写文件,则可用系统功能调用42H移动文件指针的方法实现。
调用前,将文件标记存入BX,所需移动偏移量的字节数(CX为高位部分)存放于CX:DX;调用后在DX:AX中返回读写指针移动后的位置。
移动的方式有三种:AL=0 指针从文件头移动到由CX:DX所指定的偏移量处;AL=1 指针从当前位置移动到由CX:DX所指定的偏移量处;AL=2 指针从文件尾移动到由CX:DX所指定的偏移量处;本实验通过第1题,使同学掌握利用文件标记的方法,读写一个文件;第2题在掌握文件标记的使用之后,理解利用文件标记及文件指针将两个文件合并成一个文件的过程及技术要领。
第3题进一步理解文件指针的三种移动方式的使用方法。
三、实验任务及步骤1.用文件标记读写文件编程实现,首先从键盘输入包括驱动器名、路径名、文件名及0的ASCIIZ字符串(即为指定路径下的一个文件),然后把这个文件打开并读入到内存数据缓冲区50000H(对应的逻辑地址为5000:0000)处,再换个文件名重新写入磁盘。
代码如下:DATA SEGMENTFILE1 DB 40DB ?DB 40 DUP(0)FILE2 DB 40DB ?DB 40 DUP(0)MSG1 DB 'INPUT SOURCE FILE:$'MSG2 DB 'INPUT NEW NAME:$'ENTER DB 0DH,0AH,'$'BUF DB 100 DUP(0)STACK SEGMENTDB 100 DUP(?)STACK ENDSDATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKMAIN PROC FARMOV AX,DATAMOV DS,AXLEA DX,MSG1 MOV AH,09HINT 21HLEA DX,FILE1 MOV AH,0AHINT 21HLEA SI,FILE1MOV AL,[SI+1] CBWINC SIINC SIADD SI,AXMOV BYTE PTR[SI],0LEA DX,ENTER MOV AH,9INT 21HLEA DX,FILE1+2 MOV AH,3DH MOV AL,0INT 21HMOV BX,AXMOV AH,3FH PUSH DSPUSH ESMOV CX,5000H MOV DS,CXMOV DX,0000HMOV CX,50INT 21HPOP DSPOP ESMOV AH,3EHINT 21HLEA DX,MSG2INT 21HLEA DX,FILE2MOV AH,0AHINT 21HLEA SI,FILE2MOV AL,[SI+1]CBWINC SIINC SIADD SI,AXMOV BYTE PTR[SI],0MOV AH,3CHMOV CX,00HLEA DX,FILE2+2INT 21HMOV BX,AXMOV AH,40HPUSH DSPUSH ESMOV CX,5000HMOV DS,CXMOV DX,0000HMOV CX,14INT 21HPOP DSPOP ESMOV AH,3EHINT 21HMOV AH,4CHINT 21HMAIN ENDPCODE ENDSEND MAIN运行结果如下:2.利用文件标记,从磁盘内读入两个文件到内存缓冲区,然后把这两个文件合并为一个文件存入磁盘。
试编写源程序。
代码如下:DATA SEGMENTFILE1 DB 'C:\72A.TXT',00HFILE2 DB 'C: \72B.TXT',00HFILE3 DB 'C:\72C.TXT',00HSAVE DW 0NUM DW 0SAVENEW DW 0BUF DB 100 DUP(0)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATAMAIN PROC FARMOV AX,DATAMOV DS,AXMOV ES,AXMOV AH,3DHMOV AL,0LEA DX,FILE1INT 21HMOV SAVE,AXMOV AH,3FH MOV BX,SAVE LEA DX,BUFMOV CX,255INT 21HMOV NUM,AXMOV AH,3EH MOV BX,SAVE INT 21HMOV AH,3CH MOV CX,00H LEA DX,FILE3INT 21HMOV SAVENEW,AXMOV AH,40H MOV BX,SAVENEW MOV CX,NUM LEA DX,BUFINT 21HMOV AH,3DH MOV AL,0LEA DX,FILE2INT 21HMOV SAVE,AXMOV AH,3FH MOV BX,SAVE LEA DX,BUFMOV CX,255INT 21HMOV NUM,AXMOV AH,3EH MOV BX,SAVE INT 21HMOV AH,40H MOV BX,SAVENEW MOV CX,NUMLEA DX,BUFINT 21HMOV AH,3EHMOV BX,SAVENEWINT 21HMOV AH,4CHINT 21HMAIN ENDPCODE ENDSEND MAIN运行结果如下:(运行前)(运行后)3.利用文件指针读取一个源文件,要求从文件尾处开始读取100H个字节到缓冲区,然后换个文件名存入磁盘。
试编写源程序。
代码如下:DATA SEGMENTFILE1 DB 'C:\73.TXT',00HFILE2 DB 50DB ?DB 50 DUP(0)SAVE DW 0BUF DB 256 DUP(0)STR DB 'INPUT NEW NAME:$'DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATAMAIN PROC FARMOV AX,DATAMOV DS,AXMOV ES,AXLEA DX,STRMOV AH,09HINT 21HMOV AH,3DHMOV AL,0LEA DX,FILE1INT 21HMOV SAVE,AXMOV BX,SAVEMOV AH,42HMOV CX,0MOV DX,0MOV AL,02INT 21HSUB AX,100HMOV DX,AXMOV AH,42HMOV CX,0MOV AL,0INT 21HMOV AH,3FHMOV BX,SAVELEA DX,BUFMOV CX,256INT 21HMOV AH,3EHMOV BX,SAVEINT 21HLEA SI,BUFADD SI,255MOV DI,SILEA SI,BUFMOV CX,128 AGAIN:MOV BL,[SI]XCHG BL,[DI]MOV [SI],BLINC SIDEC DILOOP AGAINLEA DX,FILE2MOV AH,0AHINT 21HLEA SI,FILE2MOV AL,[SI+1]CBWINC SIINC SIADD SI,AXMOV BYTE PTR[SI],0MOV AH,3CHMOV CX,00HLEA DX,FILE2+2INT 21HMOV BX,SAVEMOV BX,SAVEMOV AH,40HMOV CX,256LEA DX,BUFINT 21HMOV AH,3EHMOV BX,SAVEINT 21HMOV AH,4CHINT 21HMAIN ENDPCODE ENDSEND MAIN运行结果如下:4.编程实现,一边从键盘上接收字符,一边将其写入指定的文件,限定字符个数为50个。
汇编简介及语言语法大全
汇编汇编大多是指汇编语言,汇编程序。
把汇编语言翻译成机器语言的过程称为汇编。
在汇编语言中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。
这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。
于是汇编语言亦称为符号语言。
用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序,汇编程序是系统软件中语言处理的系统软件。
汇编汇编语言(Assembly Language)是面向机器的程序设计语言。
汇编语言比机器语言易于读写、易于调试和修改,同时也具有机器语言执行速度快,占内存空间少等优点,但在编写复杂程序时具有明显的局限性,汇编语言依赖于具体的机型,不能通用,也不能在不同机型之间移植。
是能完成一定任务的机器指令的集合。
常说汇编语言过时,是低级语言,并不是说汇编语言要被弃之,相反,汇编语言仍然是程序员必须了解的语言,在某些行业与领域,汇编是必不可少的,非它不可适用。
只是,现在计算机最大的领域为IT软件,也是我们常说的Windows 编程,在熟练的程序员手里,使用汇编语言编写的程序,运行效率与性能比其它语言写的程序是成倍的优秀,但是代价是需要更长的时间来优化,如果对计算机原理及编程基础不扎实,实在是得不偿失,对比现在的软件开发,已经是市场化的软件行业,加上高级语言的优秀与跨平台,一个公司不可以让一个团队使用汇编语言来编写所有的东西,花上几倍甚至几十倍的时间,不如使用其它语言来完成,只要最终结果不比汇编语言编写的差太多,就能抢先一步完成,这是市场经济下的必然结果。
但是,至今为止,还没有程序员敢断定汇编语言是不需要学的,一个不懂汇编语言的程序员,只是三流的程序员,这是大部分人的共识,同时,技术汇编语言(Assembly Language)是面向机器的程序设计语言精湛的汇编程序员,已经脱离软件开发,挤身于工业电子编程中,一个电子工程师,主要开发语言就是汇编,c语言使用只占极少部分,而电子开发工程师是千金难求,在一些工业公司,一个核心的电子工程师比其它任何职员待遇都高,对比起来,一般电子工程师待遇是程序员的十倍以上。
汇编语言入门教程
汇编语言入门教程2007-04—29 22:04对初学者而言,汇编的许多命令太复杂,往往学习很长时间也写不出一个漂漂亮亮的程序,以致妨碍了我们学习汇编的兴趣,不少人就此放弃.所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩DEBUG,有时CRACK出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样)。
某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了。
为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ……).但是想在啰里吧嗦的教科书中完成上述目标,谈何容易,所以本人整理了这篇超浓缩(用WINZIP、WINRAR…依次压迫,嘿嘿!)教程.大言不惭的说,看通本文,你完全可以“不经意”间在前辈或是后生卖弄一下DEBUG,很有成就感的,试试看!那么――这个接下来呢?――Here we go!(阅读时看不懂不要紧,下文必有分解)因为汇编是通过CPU和内存跟硬件对话的,所以我们不得不先了解一下CPU和内存:(关于数的进制问题在此不提)CPU是可以执行电脑所有算术╱逻辑运算与基本I/O 控制功能的一块芯片.一种汇编语言只能用于特定的CPU。
也就是说,不同的CPU 其汇编语言的指令语法亦不相同。
个人电脑由1981年推出至今,其CPU发展过程为:8086→80286→80386→80486→PENTIUM →……,还有AMD、CYRIX等旁支。
后面兼容前面CPU的功能,只不过多了些指令(如多能奔腾的MMX指令集)、增大了寄存器(如386的32位EAX)、增多了寄存器(如486的FS)。
为确保汇编程序可以适用于各种机型,所以推荐使用8086汇编语言,其兼容性最佳.本文所提均为8086汇编语言。
寄存器(Register)是CPU内部的元件,所以在寄存器之间的数据传送非常快。
用途:1。
汇编语言文件的读写源代码
汇编语言文件的读写源代码一、概述汇编语言是一种低级语言,可以直接操作计算机的硬件资源。
在使用汇编语言编程时,文件的读写是非常常见的操作。
本文将介绍如何使用汇编语言进行文件的读写操作,并给出相应的源代码示例。
二、文件读取1. 打开文件在进行文件读取操作之前,首先需要打开待读取的文件。
以下是一个打开文件的汇编语言源代码示例:```assemblysection .datafilename db 'example.txt', 0mode db 'r', 0file dd 0section .textglobal _start_start:; 打开文件mov eax, 5mov ebx, filenamemov ecx, modeint 0x80mov [file], eax; ...```在上述示例中,首先定义了一个变量 `filename` 用于存储待读取文件的文件名,变量 `mode` 用于指定打开文件的模式。
然后使用系统调用 `int 0x80` 进行文件打开操作,并将返回的文件描述符保存在变量`file` 中。
2. 读取文件内容文件打开之后,就可以开始读取文件的内容了。
以下是一个读取文件内容的汇编语言源代码示例:```assemblysection .bssbuffer resb 1024section .text; ...; 读取文件内容mov eax, 3mov ebx, [file]mov ecx, buffermov edx, 1024int 0x80; ...```在上述示例中,定义了一个缓冲区变量 `buffer` 来存储读取的文件内容,并使用系统调用 `int 0x80` 进行文件读取操作。
读取的文件内容将被存储到缓冲区变量 `buffer` 中。
三、文件写入1. 创建文件在进行文件写入操作之前,有时需要先创建一个新的文件。
以下是一个创建文件的汇编语言源代码示例:```assemblysection .datafilename db 'output.txt', 0mode db 'w', 0file dd 0section .textglobal _start_start:; 创建文件mov eax, 8mov ebx, filenamemov ecx, modemov edx, 0777int 0x80mov [file], eax; ...```在上述示例中,首先定义了一个变量 `filename` 用于存储待创建文件的文件名,变量 `mode` 用于指定创建文件的模式。
51读写SD汇编语言
DSEG AT 30H
CS BIT P2.0 ;SD卡接口
CLK BIT P2.1
SPI_IN BIT P2.2
SPI_OUT BIT P2.3
RS BIT P2.4 ;12864接口
RW BIT P2.5
E BIT P2.6
ResponceSD EQU 30H ;保存SD卡应答信号
;说明:上升沿写入数据,高位开始,从A中写入.CS/CLK/SPI_IN
SPI_WriteByte:
MOV R4,#08H
CLR CLK ;L
LCALL F_DelayShort
Loop_WriteByte:
RLC A
JC L_Next1
CLR SPI_IN
LJMP L_Next2
;<<SPI读1字节>>
;出口参数:A
;说明:下降沿读出数据,高位开始,保存到A中.CS/CLK/SPI_OUT
SPI_ReadByte:
MOV R4,#08H
SETB CLK ;H
LCALL F_DelayShort
L_ReadByte:
MOV C,SPI_OUT
LCALL F_DelayShort
/***********************************************************
名称: SD卡读写 *
描述: SD卡与单片机连接读写数据,另外MCU与12864液晶相连 *
硬件: SD卡与MCU的P2.0-P2.3相连,12864与P1口和P2.4-2.6相连 * *
汇编语言对文件加密解密
;************************************主程序中用到的所有宏定义*********************************************************
fopen macro filename,type,handle ;打开文件的宏(文件名,属性,文件代号)
fname_in db 20 dup(?),? ;为文件名准备的缓冲区
handle_in dw ? ;输入文件代号
error1 db "open file error!",0dH,0aH,'$' ;出错提示信息
quit_msg db "press any key to continue...$"
mov cx,size
lea dx,buffer
int 21H
endm
fclose macro handle ;关闭文件的宏(文件代号)
mov ah,3eH
mov bx,handle
int 21H
endm
pause macro ;暂停的宏
pause ;暂停
quit ;退出
main endp
;------------------------------------------加密模块--------------------------------------------
encryex proc near
in_msg1 db "input the source file name:",0DH,0AH,'$' ;输入提示信息
succmsg1 db "encry successfully!",0DH,0AH,'$'
在8086汇编语言中ax,_bx,_cx,_dx四个寄存器的常见用途
在8086汇编语言中ax, bx, cx, dx四个寄存器的常见用途1. 引言1.1 概述在8086汇编语言中,AX、BX、CX和DX是四个常见的寄存器。
这些寄存器具有不同的功能和用途,可以提供对数据的临时存储和处理。
它们在程序设计中扮演着重要的角色,并且对于编写高效且功能完善的汇编代码至关重要。
1.2 文章结构本文将详细讨论AX、BX、CX和DX四个寄存器的常见用途。
首先,我们将探讨AX寄存器及其在累加、函数返回值传递以及数据处理和运算中的作用。
然后,我们将研究BX寄存器,在基址寄存器、指针地址存储以及字符串操作方面的应用。
接下来,我们将介绍CX寄存器在计数与循环控制、位移与移位操作以及I/O 端口控制方面的功能。
最后,我们将讲解DX寄存器在数据传输、中断向量以及I/O端口地址存储方面所起到的重要作用。
1.3 目的通过深入理解AX、BX、CX和DX四个常用寄存器以及它们各自的应用领域,读者将能够更好地理解如何在8086汇编语言中使用这些寄存器,并且能够优化自己的编程技巧。
此外,对于那些希望进一步学习汇编语言的人来说,本文还可作为入门指南,提供了有关寄存器功能和用途的基本知识。
2. AX寄存器的常见用途:2.1 累加器:AX寄存器是8086汇编语言中最常用的累加器。
作为一个通用寄存器,它被广泛用于执行不同类型的运算,例如加法、减法、乘法和除法操作。
在进行加法或减法运算时,我们可以将待操作的数值加载到AX寄存器,并且可以通过执行ADD或SUB指令来实现加法或减法操作。
以乘法为例,其中一个乘数会被放入AX寄存器中,并通过执行MUL(无符号)或IMUL(有符号)指令与另一个操作数进行相乘。
2.2 存储函数返回值:在很多情况下,子程序会将其返回值保存在AX寄存器中。
当调用某个函数或子程序时,该函数或子程序可能会要求将结果返回给调用者。
这时候,函数会将结果保存在AX寄存器中,并通过RETN指令将控制权交还给调用者,从而返回函数的执行结果。
汇编中文件的读写
汇怎么读汇编语言实验报告(七)班级:01540802班姓名:南征学号: 20080705信息与电子学院实验七文件的读写一、实验目的二、实验要点磁盘文件的读写有两种方法,一种称为文件控制块;另一种方法称为文件标记,前者在读写文件时首先要设定文件控制块,知名文件所在的当前磁盘的驱动器、文件名,同时还要制定所读写的文件所处的当前块号、当前记录号、记录长度等参量,此外还需要设置磁盘传输区。
在读磁盘数据文件时,应先将磁盘上有关数据读入磁盘传输区,然后再传送至目的的内存区。
在写磁盘数据文件时,要写入磁盘文件的数据也必须先送入磁盘传输区,然后再执行写操作。
此种方法的缺点是不支持树形目录结构。
目前常用的方法是利用文件标记读写文件,无论用什么方法读写文件,都要解决以下几个问题:A) 用户程序要告诉操作系统将要存取那个文件。
B) 无论是从磁盘独处的数据,还是要写入磁盘的数据都必须存放在一个制定的内存缓冲区中,这个内存缓冲区叫数据传输区(DTA)。
C) 在读一个磁盘文件之前,要先打开文件,然后才能将文件内容读入内存。
而在读写一个文件之前,要先建立一个新文件名,再将内存中的内容写入磁盘。
D) 在存取文件之后,特别是在写入文件之后,务必将此文件关闭。
利用文件标记读写文件的主要特点是:通过建立文件、打开文件,将磁盘路径名、文件名转换为文件标记或件号,在以后读写文件的操作中均要与文件标记打交道。
在一个系统中,可同时打开多个文件,并配置相应的文件标记。
在利用文件标记读写磁盘文件是要掌握以下几个要点:1) 使用建立文件、打开文件系统功能之前,都必须将DS:DX指向驱动器名、路径名、文件名和以数值零为结尾的ASCIIZ字符串的首地址。
2) 对于一个新文件要用3CH系统功能调用,建立文件。
(如果不是新文件,此步骤可略)3) 已存在的文件则利用3DH系统功能调用,打开此文件。
4) 如果文件建立、打开成功,则CF=0,并且在AX寄存器中返回文件标记。
北京理工大学电子信息类汇编语言实验报告――文件操作.
第六章磁盘文件存取实验(设计性实验一、实验要求和目的1. 理解文件、目录的概念;2. 了解 FCB(文件控制块方式文件管理方法;3. 掌握文件代号式文件存取方式;4. 学习使用文件指针读取文件二、软硬件环境1. 硬件环境:计算机系统 windows;2. 软件环境:装有 MASM、DEBUG、LINK、等应用程序。
三、实验涉及的主要知识单元DOS 功能调用中断(INT 21H提供了两类磁盘文件管理功能,一类是 FCB(文件控制块方式,另一类是文件代号式存取方式。
对于文件的管理,实际上是对文件的读写管理, DOS 设计了四种存取文件方式:顺序存取方式、随机存取方式、随机分块存取方式和代号法存取方式。
文件的处理步骤A 写之前必须先建立文件、读之前必须先打开文件。
B 写文件之后一定要关闭文件。
通过关闭文件,使操作系统确认此文件放在磁盘哪一部分,写后不关闭会导致写入文件不完整。
1、文件代号式存取方式: 当用户需要打开或建立一个文件时,必须提供文件标识符。
文件标识符用ASCII Z 字符串表示。
ASCII Z 字符串是指文件标识符的 ASCII 字符串后面再加1 个“0”字符。
文件标识符的字符串包括驱动器名、路径名和文件名。
其格式为[d:][path]filename[.exe]其中 d 为驱动器名,path 为路径名,.exe 为文件名后缀。
中断 21H 提供了许多有关目录和文件操作的功能,其中文件代号式存取方式常用的功能如下:2、操作目录的常用功能39H——创建目录 3BH——设置当前目录3AH——删除目录 47H——读取当前目录有关中断功能的详细描述和调用参数在此从略,需要查阅者可参阅相关资料之目录控制功能。
3、用文件句柄操作文件的常用功能3CH——创建文件 4EH——查找到第一个文件3DH——打开文件 4FH——查找下一个文件3EH——关闭文件 56H——文件换名3FH——读文件或设备 57H——读取/设置文件的日期和时间40H——写文件或设备 5AH——创建临时文件41H——删除文件 5BH——创建新文件42H——设置文件指针 67H——设置文件句柄数(最多文件数43H——读取/设置文件属性 6CH——扩展的打开文件功能有关中断功能的详细描述和调用参数在此从略,需要查阅者可参阅相关资料之文件操作功能。
汇编常用API函数
【文件操作类的api函数主要是包含】:文件的创建; createfile | 文件的读写;writefile |获取文件大小;getfilesize | 取文件属性;GetFileAttributesA|设置文件属性;setfileattribute|复制文件 copyfile|移动文件movefile | 关闭文件句柄;closehandle1、sleep 延迟函数004A2015 68 E8030000 push 0x3E8 1000毫秒==1秒004A201A E8 41C2F6FF call <jmp.&kernel32.Sleep>004A1E48 > 68 E8030000 push 3E8004A1E4D FF15 70834A00 call dword ptrds:[<&kernel32.Sleep>] ; kernel32.Sleeppush xxxxcall [xxxxxxxx] 模板CTRL+N查找函数参考-------------------------------------------2、ExitProcess 中止一个进程004A20E0 6A 00 push 0x0 (终止本进程)004A20E2 E8 4D4DF6FF call <jmp.&kernel32.ExitProcess>004A1E48 > 6A 00 push 0004A1E4A FF15 E0844A00 call dword ptrds:[<&kernel32.ExitProc>; kernel32.ExitProcess-------------------------------------------3、WinExec 调用运行另一个程序的函数push 0push 路径call [xxxxxxxx]004A2078 50 push eax004A2079 E8 EE50F6FF call <jmp.&kernel32.WinExec>004A1E48 > 6A 01 push 0x1 //显示运行004A1E4A 68 721E4A00 push004A1E72 ; ASCII "c:\d.exe"004A1E4F FF15 48834A00 call dword ptr[<&kernel32.WinExec>] ; kernel32.WinExec----------------------------------------------4、GetLocalTime 获取本地时间的函数0040ADF3 50 PUSH EAX0040ADF4 E8 3BC1FFFF CALL <JMP.&kernel32.GetLocalTime> DB 07 2011年月周日时分秒004A1E49 8D85 70FEFFFF lea eax, dword ptr [ebp-0x190]004A1E4F 50 push eax //这个里面004A1E50 FF15 60844A00 call dword ptr[<&kernel32.GetLocalTime>] ;00473AD5 8D45 EC lea eax, dword ptr [ebp-0x14] 00473AD8 50 push eax00473AD9 E8 A634F9FF call <jmp.&kernel32.GetSystemTime> --------------------------------------------------------------5、GetSystemDirectoryA 获取系统目录的函数call <jmp.&kernel32.GetWindowsDirectoryA>0049FD5E 68 FF000000 push 0xFF 大小0049FD63 8D85 00FFFFFF lea eax, dword ptr [ebp-0x100] 0049FD69 50 push eax0049FD6A E8 6D72F6FF call<jmp.&kernel32.GetWindowsDirectoryA>00401006 6A 20 push 0x20 bufer size00401008 68 00234000 push 00402300 bufer address 0040100D FF15 04314000 call GetSystemDirectoryA004A1E48 > 68 00010000 push 0x100004A1E4D 8D85 00FFFFFF lea eax, dword ptr [ebp-0x100]004A1E53 50 push eax004A1E54 FF15 23204C00 call dword ptr[<&kernel32.GetSystemDirectoryA>] ;xp c:\windows\system322000--------------------------------------------------------------6、GetTickCount 从你开机----现在所经历的毫秒数 1000 ==1秒GetTickCount 无参数有返回值获取系统启动时间的函数返回数据存放在eax寄存器中;005C7A02005DCED4005E06DC获取到这个数据,然后将他写入到程序里面。
汇编In Out指令
x86系列的CPU是指最早由Intel公司生产的8086系列以及以后的后继产品,也包括了各CPU生产厂商仿制的产品。但不包括后来的各种形式的64位的CPU。
段是一个存储概念。
下面描述的主要是我的想象,你可以把它当成演义来看:),不必当真。
从8086 开始,Intel的CPU就已经是16位的了。所谓16位,是指它的数据总线,地址总线
我上面的描述其实并不是事实,或者至少有一部分不是事实。那就是:286中的段寄存器存放的不再是简单的段基址了。它存放的是一个叫做段选择子的东西,这个东西指向存储空间中的段描述符表中的某一项,或者简单的说,指向段描述符。段描述符里面存放的才是真正的段基址什么的。用比较直白的术语,我们说它引入了一重间接性。
(注意,地址总线并不是如此的,后面会有详细的说明,事实上,它的地址总线是20位的),各个寄存器都是16位宽的。那真是一个简单的年代。16位地址总线意味着可以寻址64K的地址空间。甚至在那个年代,64K也有点小了。所以Intel决定(配合IBM的要求)采用20位地址总线。但这引发了一个问题,那就是:指令集如何设置?要知道,20位比16位多了4个位,这四个位放在何处?寄存器都是16位的!聪明的Intel的工程师开始想到了一个办法(我估计是受DEC的启发,它的CPU就是分段式的内存,不过, Intel的分段跟他还是有很大区别的,DEC的是不重叠的分段,而Intel的分段可以重叠),就是把地址空间分成两部分,一部分叫作段基址,一部分叫作段内地址。段内地址就是原始的16位地址,所以,段的大小最大是64K,那么段基址怎么办?我们知道,段基址要在20位的地址空间中(也就是1M的地址空间)表示一个地址,最合理的选择就是20位。但是,Intel的工程师当时认为,在一个16位的CPU中放置一个20位的寄存器不合情理,所以采用了一个聪明的偷懒办法。用一个16位的寄存器表达一个低4位为零的20位地址。说得明确一点,我用16进制表示,一个16位的寄存器,其值为NNNN,那么我们就把它看成NNNN0这样一个地址。这就是段基址寄存器。简单的叫做段寄存器。在我们想访问1M地址空间中的任意一个地址区域的时候,我们可以把段寄存器的值调整的靠近(所谓的靠近,也就是比这个地址空间小,但是不小于64K的某个地方)这个地址空间,然后通过段基址和段内地址之和,就可以访问1M内任意的地址空间了。修整段寄存器地址的这个动作叫作段切换。段内地址仍然是16位长,这也限制了段的长度是64K。看到这儿,你或许会想起些什么,或许会对所谓的近指针、远指针的概念有了一些回忆。哈哈。机制描述完了,我们开始看看这个设计引发的一些有趣的限制和问题。首先,段基址被限定为低4位为0,也就是NNNN0这种形式,那么,段基址一定是16的整数倍。呵呵,这个16被称作para(paragraph,段!注意,我们上面所描述的段被Intel 的工程师称为segment)。其次,由于FFFF0 + FFFF寻址的地址已经大于1M了(事实上,整整比1M大了一个segment的长度,64K),而实际上20位地址总线确实只能寻址1M的地址空间,这就说明了我们Intel工程师的这个设计其实没有达标!呵呵,确实没有想到会有这么一个问题。后来,应该是某个Intel的心理稍微有点变态的家伙说:我们让他回环吧。一开始,估计大家都觉得很失败,后来,大家都不禁被这个想法逗乐了,回环就这样被确定下来了。我说说回环是什么。很有意思。由于段基址+段内地址可以表达超过1M的地址空间,而地址总线只能寻址1M的地址空间,所以,所有超过1M地址空间的地址都减去1M。也就是说,所有大于1M的地址空间都重新从0开始计算,就好像又绕回来了一样。这就是回环。
