怎样用汇编语言读写文件

怎样用汇编语言读写文件,第1张

所谓 *** 作系统,一个主要功能就是管理硬盘这样的外部存储器,当这些存储器的尺寸非常大,而且存储器种类、读写速率、数据组织各有不同时,需要很复杂而且灵活、适应面广的程序设计

如果用汇编语言读写文件,一般要简化这些要求郑纤,比如假设只针对Windows的FAT格式的存储格式,汇编程序需要能解析FAT格式硬盘的存储格式,从FAT格式中能访问到文件实际存储位置,这就使汇编很麻烦了,汇编不是来做这种复杂而人盯丛毕性化的工作的

普通汇编程序要读写硬盘,一般采用无格式的方式,需要自己设计简单的文件管理,这样可以快速简单地保存数据到硬盘中,但保存的数据无法凯芹简单被windows等磁盘 *** 作系统读取,还需要转换才行。

**************************************

AT24C04测试程序 供参考

工作频率: 12.000MHz

**************************************

SCL BIT P2.0 AT24C04的时钟线

SDA BIT P2.1 AT24C04的数败备据线

BUF EQU 30H数据缓存区

**************************************

ORG 0

JMP Reset

ORG 100H

Reset:

CALL AT24C04_WritePage 写一页数据

CALL Delay5ms 写一页数据需延时5ms

CALL AT24C04_ReadPage 读一页数据

JMP $

**************************************

向AT24C04写1页(16字节)数据

将TESTDATA开始的16个测试数据写如设备的00~0F地址

入口参数:无

出口参数:无

**************************************

AT24C04_WritePage:

CALL AT24C04_Start 起始信号

MOV A,#0A0H 发送设备地址+写信号

CALL AT24C04_SendByte 发送

MOV A,#00H 发送存储单元地址

CALL AT24C04_SendByte 发送

MOV R0,#16 16字节计数衫配器

MOV DPTR,#TESTDATA 测试数据首地址

WriteNext:

CLR A 读取测试数据

MOVC A,@A+DPTR

CALL AT24C04_SendByte 写入设备

INC DPTR准备下一个数据的地址

DJNZ R0,WriteNext 判断16字节是否完成

CALL AT24C04_Stop 停止信号

RET

TESTDATA:

DB 000H,011H,022H,033H,044H,055H,066H,077H

DB 088H,099H,0AAH,0BBH,0CCH,0DDH,0EEH,0FFH

**************************************

从AT24C04读取1页(16字节)数据

将设备的00~0F地址中的数据读出存放在DATA区的BUF中

入口参数:无

出口参数:无

**************************************

AT24C04_ReadPage:

CALL AT24C04_Start 起始信号

MOV A,#0A0H 发送设备地址+写信号

CALL AT24C04_SendByte 发送

MOV A,#00H 发送存储单元地址

CALL AT24C04_SendByte 发送

CALL AT24C04_Start 起始信号

MOV A,#0A1H 发送设备地址+读信号

CALL AT24C04_SendByte 发送

MOV R0,#16 16字节计数器

MOV R1,#BUF 数据缓冲区首地址

ReadNext:

CALL AT24C04_RecvByte 读取数据

MOV @R1,A 保存数据察塌毁

CJNE R0,#2,$+3 判断回应ACK还是NAK

CALL AT24C04_SendACK发送应答信号

INC R1 缓冲区地址加1

DJNZ R0,ReadNext判断16字节是否完成

CALL AT24C04_Stop 停止信号

RET

**************************************

延时5微秒

不同的工作环境,需要调整此函数

入口参数:无

出口参数:无

**************************************

Delay5us: 2 当改用1T的MCU时,请调整此延时函数

NOP 1

RET 2

**************************************

延时5毫秒

不同的工作环境,需要调整此函数

入口参数:无

出口参数:无

**************************************

Delay5ms: 2 当改用1T的MCU时,请调整此延时函数

PUSH ACC2

PUSH DPL2

PUSH DPH2

MOV DPTR,#-500 2

Delay5ms1:

NOP 1

NOP 1

NOP 1

NOP 1

INC DPTR2

MOV A,DPL 1

ORL A,DPH 1

JNZ Delay5ms1 2

POP DPH 2

POP DPL 2

POP ACC 2

RET 2

**************************************

起始信号

入口参数:无

出口参数:无

**************************************

AT24C04_Start:

SETB SDA

SETB SCL拉高时钟线

CALL Delay5us 延时

CLR SDA 产生下降沿

CALL Delay5us 延时

CLR SCL 拉低时钟线

RET

**************************************

停止信号

入口参数:无

出口参数:无

**************************************

AT24C04_Stop:

CLR SDA

SETB SCL拉高时钟线

CALL Delay5us 延时

SETB SDA产生上升沿

CALL Delay5us 延时

RET

**************************************

发送应答信号

入口参数:C (0:ACK 1:NAK)

出口参数:无

**************************************

AT24C04_SendACK:

MOV SDA,C 写应答信号

SETB SCL拉高时钟线

CALL Delay5us 延时

CLR SCL 拉低时钟线

CALL Delay5us 延时

RET

**************************************

接收应答信号

入口参数:无

出口参数:C

**************************************

AT24C04_RecvACK:

SETB SCL拉高时钟线

CALL Delay5us 延时

MOV C,SDA 读应答信号

CLR SCL 拉低时钟线

CALL Delay5us 延时

RET

**************************************

向IIC总线发送一个字节数据

入口参数:ACC

出口参数:无

**************************************

AT24C04_SendByte:

PUSH 0

MOV 0,#88位计数器

SendNext:

RLC A 移出数据的最高位

MOV SDA,C 送数据口

SETB SCL拉高时钟线

CALL Delay5us 延时

CLR SCL 拉低时钟线

CALL Delay5us 延时

DJNZ 0,SendNext 判断8位数据是否发送完成

POP 0

JMP AT24C04_RecvACK 接收应答信号

RET

**************************************

从IIC总线接收一个字节数据

入口参数:无

出口参数:ACC

**************************************

AT24C04_RecvByte:

SETB SDA使能内部上拉,准备读取数据

PUSH 0

MOV 0,#88位计数器

RecvNext:

SETB SCL拉高时钟线

CALL Delay5us 延时

MOV C,SDA 读数据口

RLC A 保存数据

CLR SCL 拉低时钟线

CALL Delay5us 延时

DJNZ 0,RecvNext 判断8位数据是否接收完成

POP 0

RET

**************************************

END

感楼主诚意,费了九牛二虎之力,方才完成。不知能否满足要求。

本程序通过编译蠢斗,运行正确

Code Segment

Assume CS:Code,DS:Code

CR equ 000DH

LF equ 000AH

KBBack equ 0008H

Name_Len equ 18 用户名最大长度

Pass_Len equ 8 密码最大长度

-------------------------------------

将用户名和密码定义为一个结构类型

User Struc 成绩单结构类型

User_Name db Name_Len dup(?) 用户名

Name_Lenth db ? 用户名实际长度

Pass_Word db Name_Len dup(?) 密码

Pass_Lenth db ? 密码实际长度

User EndS

--------------------帆局-----------------

功能:显示指定地址(Str_Addr)的字符串

入口:

Str_Addr=字符串地址(要求在数据段)

用法: Output Str_Addr

用法举例:Output PromptStr

Output MACRO Str_Addr

lea dx,Str_Addr

mov ah,9

int 21h

EndM

---------------------------------带轿磨----

功能:取光标位置

入口:无

出口:DH=行号,DL=列号

GetCursor Proc Near

PUSH AX

PUSH BX

PUSH CX

PUSH DX

XOR BX,BX

MOV AH,3

INT 10H

MOV Cursor_Row,DH

MOV Cursor_Col,DL

POP DX

POP CX

POP BX

POP AX

RET

Cursor_Row DB ?

Cursor_Col DB ?

GetCursor EndP

-------------------------------------

功能:置光标位置

入口:Cursor_Row=行坐标Cursor_Col: 列坐标)

SetCursor Proc Near

PUSH DX

PUSH CX

PUSH BX

PUSH AX

MOV DH,Cursor_Row

MOV DL,Cursor_Col

XOR BX,BX

MOV AH,2

INT 10H

POP AX

POP BX

POP CX

POP DX

RET

SetCursor EndP

-------------------------------------

窗口上滚指定行数

Roll_Up Proc Near

xor bh,bh 显示页号

mov ah,8 读光标位置的字符和属性

int 10h

mov bh,ah 上滚窗口空行属性

mov cx,100h 左上角坐标

mov al,5

mov dx,54fh 右下角坐标

mov ah,6

int 10h

ret

Roll_Up EndP

-------------------------------------

功能:输入指定位数的用户密码,实际输入的密码字符以“*”显示,并有回空纠错功能

入口:di=密码输入缓冲区地址

出口:AL=实际输入的密码字符数

Input_PassW Proc Near

push di

mov cx,Pass_Len 密码最大长度

@@Input: call GetCursor 取光标位置

mov ah,7 从键盘接受一个字符

int 21h

cmp al,CR 回车符?

jz @@Calc_Chrs 是,结束密码输入,转去计算实际输入的密码字符数

cmp al,KBBack

jz @@KB_Back 若是回空键,重新输入

stosb 保存输入的字符

mov dl,'*'

mov ah,2

int 21h

jmp @@KBBack

@@KB_Back: dec Cursor_Col

inc cx

dec di

@@KBBack: inc Cursor_Col

call SetCursor 置光标位置

loop @@Input 接受下一个数字

@@Calc_Chrs:mov cx,di

pop di

sub cx,di

cmp cl,[si.Pass_Lenth]

jnz @@Pass_Err 密码长度不等

mov cl,[si.Pass_Lenth]

xor ch,ch

push si

lea si,[si.Pass_Word]

cld

repz cmpsb 比较密码是否正确

pop si

jcxz $+4

@@Pass_Err: clc 进位标志复位,表示密码不正确

ret

stc 进位标志置位,表示密码正确

ret

Input_PassW EndP

-------------------------------------

Again_Input Proc Near

Output Input_Again 提示:是否重新输入用户名

mov ah,1 从键盘接受一个字符

int 21h

or al,20h 转换成小写,大小写不敏感

cmp al,'y' 重新输入?

jnz $+7 不

call Roll_Up 窗口上滚指定行数

stc 进位标志置位,表示重复前面的 *** 作

ret

cmp al,'n' 不重新输入?

jnz Again_Input 不是,非有效字母,重新输入

clc 进位标志复位,表示放弃前面的 *** 作

ret

Again_Input EndP

-------------------------------------

Users equ 5 用户数

Even

User_Inform User <'richcon',7,'12345678',8>

User <'WangMing',8,'21345678',8>

User <'ZhangHongQiao',13,'13245678',8>

User <'LiYan',5,'12435678',8>

User <'XuPengYu',12,'12354678',8>

Prompt_User db 'User name: $'

Prompt_Word db 'Pass word: $'

Empty_Error db 7,CR,LF,CR,LF,'User name is empty.$'

Register_No db 7,CR,LF,CR,LF,'No register.$'

Pass_Error db 7,CR,LF,CR,LF,'Pass word error!$'

Welcome db 7,CR,LF,CR,LF,'WELCOME$',0

Input_Again db CR,LF,CR,LF,'Do you input user name again(y/n)?$'

Start: push cs

pop ds 使数据段与代码段同段

push cs

pop es 使附加段与代码段同段

Output Prompt_User 提示输入用户名

call GetCursor 取光标位置

Input_Name: call SetCursor 置光标位置

lea dx,Buffer 数据缓冲区地址

mov ah,0ah 键盘缓冲区输入

int 21h

lea si,Buffer[1] 实际输入的字符数地址

lodsb 取实际输入的字符数

test al,al 空串?

jnz Valid_Test 不是,检测输入的用户是否注册

Output Empty_Error 提示用户名为空

jmp Input_Name 重新输入用户名

Valid_Test: mov cx,Users 注册用户数

lea si,User_Inform 注册用户信息地址

Valid_Test0:cmp al,[si.Name_Lenth] 输入的用户名长度=用户名实际长度?

jnz Next_One 不相等,与下一个注册用户名比较

push cx

push si

lea si,[si.User_Name]

lea di,Buffer[2] 实际输入的用户名地址

mov cl,al

xor ch,ch

cld

repz cmpsb 比较用户名是否已注册

stc 进位标志置位,表示用户名已注册

jcxz $+3

clc 进位标志复位,表示用户名未注册

pop si

pop cx

jc Input_Pass 用户名已注册,转去输入用户密码

Next_One: add si,type User 下一个注册用户信息地址

loop Valid_Test0

Output Register_No 提示:非注册用户

call Again_Input 是否继续

jc Input_Name 进位标志置位,转去重新输入用户名

jmp Exit_Proc 不重新输入用户名,结束程序

Input_Pass: mov word ptr Cursor_Row,1

call SetCursor 置光标位置

Output Prompt_Word 提示输入密码

lea di,Buffer 密码缓冲区地址

call Input_PassW 输入密码

jc @@Welcome 密码输入正确,显示欢迎信息

Output Pass_Error 提示密码输入错误

call Again_Input 是否继续

jc Input_Pass 进位标志置位,转去重新输入密码

jmp Exit_Proc 不重新输入密码,结束程序

@@Welcome: Output Welcome 显示欢迎信息

Exit_Proc: mov ah,4ch 结束程序

int 21h

Buffer db 20 数据缓冲区

Code ENDS

END Start 编译到此结束


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12211430.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存