linux汇编读取文件操作,4、Linux汇编——文件中结构化数据的操作(上)

1、概述

本篇主要针对如下结构型记录,编写程序进行处理。主要有:读数据操作、修改数据、写数据操作。每个程序将分开书写。同时,本篇程序使用新技术,将几段代码分别存放在不同文件中。

本程序包含三个部分:(1)将三个记录写入文件中

(2)显示文件中的记录

(3)将每个记录中的年龄

2、记录结构:

采用外文名字进行存储:名——40字节;姓——40字节;地址——240字节;年龄——4字节

由以上结构,定义如下常量,并存于文件record-def.s文件中:

.equ RECORD_FIRSTNAME, 0

.equ RECORD_LASTNAME, 40

.equ RECORD_ADDRESS, 80

.equ RECORD_AGE, 320

.equ RECORD_SIZE, 324

以下为读取文件操作中常用的常数,存储在文件linux.s中:

#linux常量定义

#系统调用号

.equ SYS_EXIT, 1

.equ SYS_READ, 3

.equ SYS_WRITE, 4

.equ SYS_OPEN, 5

.equ SYS_CLOSE, 6

.equ SYS_BRK, 45

#系统调用中断号

.equ LINUX_SYSCALL, 0x80

#标准文件描述符

.equ STDIN, 0

.equ STDOUT,1

.equ STDERR, 2

#通用状态码

.equ END_OF_FILE, 0

3、读、写函数

1、读函数

下面函数放在read-record.s文件中

.include "record-def.s"

.include "linux.s"

#目的:该函数根据文件描述符读取一条记录

#输入:文件描述符、缓冲区

#栈局部变量

.equ ST_READ_BUFFER, 8

.equ ST_FILEDES, 12

.section  .text

.globl read_record

.type read_record, @function

read_record:    pushl %ebp

movl %esp, %ebp

pushl %ebx    #如下图为当前栈中的内容

movl ST_FILEDES(%ebp), %ebx

movl ST_READ_BUFFER(%ebp), %ecx

movl $RECORD_SIZE, %edx

movl $SYS_READ, %eax      #由于系统调用将返回值传给%eax,所以需将该值传回给调用程序

int $LINUX_SYSCALL

popl %ebx

movl %ebp, %esp

popl %ebp

ret

5473eeae2ab734262c3c389e8b4a7acc.png

2、写函数

下面函数放在write-record.s文件中

.include "record-def.s"

.include "linux.s"

#目的:将一条记录写入文件中

#输入:文件描述符和缓冲

#输出:状态码

#栈局部变量

.equ ST_WRITE_BUFFER, 8

.equ ST_FILEDES, 12

.section .text

.globl write_record

.type write_record, @function

write_record:    pushl %ebp

movl %esp, %ebp

pushl %ebx

movl $SYS_WRITE, %eax

movl $ST_FILEDES(%ebp), %ebx

movl $ST_WRITE_BUFFER(%ebp),%ecx

movl $RECORD_SIZE, %edx

int $LINUX_SYSCALL

popl %ebp, %esp

popl %ebp

ret

4、将三条硬编码记录写入文件:

具体步骤为:打开文件,写3条记录,关闭文件。输入以下代码到write-records.s文件中

.include "record-def.s"

.include "linux.s"

.section .data

#由于每个数据长度不一致,所以使用空字节“0”填充到适当长度

#.rept是用于填充数据的伪指令,.rept和.endr之间的段重复指定次数

record1:    .ascii "ming\0" #名

.rept 35  #用0填充剩下的32个字节,填充满40字节

.byte 0

.endr

.ascii "Li\0"  #姓

.rept 37     #填充到40字节

.byte 0

.endr

.ascii "Beijing\0"  #地址

.rept 232     #填充到240字节

.byte 0

.endr

.long 45    #年龄

record2:    .ascii "Lang\0" #名

.rept 35  #用0填充剩下的32个字节,填充满40字节

.byte 0

.endr

.ascii "Qi\0"  #姓

.rept 37     #填充到40字节

.byte 0

.endr

.ascii "Daliang\0"  #地址

.rept 232     #填充到240字节

.byte 0

.endr

.long 23    #年龄

record3:    .ascii "Yong\0" #名

.rept 35  #用0填充剩下的32个字节,填充满40字节

.byte 0

.endr

.ascii "Da\0"  #姓

.rept 37     #填充到40字节

.byte 0

.endr

.ascii "Langfan\0"  #地址

.rept 232     #填充到240字节

.byte 0

.endr

.long 28    #年龄

file_name:  .ascii "test.dat\0"  #写入的文件名

.equ ST_FILE_DESCRIPTOR, -4

.globl _start

_start:     movl %esp, %ebp

subl $4, %esp          #为文件描述符分配空间

#打开文件

movl $SYS_OPEN, %eax

movl $file_name, %ebx

movl $0101, %ecx     #如果文件不存在则创建,打开文件用于写入数据

movl $0666, %edx

int $LINUX_SYSCALL

movl %eax, ST_FILE_DESCRIPTOR(%ebp)    #存储文件描述符

#写第一条记录

pushl ST_FILE_DESCRIPTOR(%ebp)  #文件描述符

pushl $record1                    #记录的地址,即缓冲区的地址

call write_record

addl $8, %esp            #回收空间

#写第二条记录

pushl ST_FILE_DESCRIPTOR(%ebp)  #文件描述符

pushl $record2                   #记录的地址

call write_record

addl $8, %esp            #回收空间

#写第三条记录

pushl ST_FILE_DESCRIPTOR(%ebp)  #文件描述符

pushl $record3                   #记录的地址

call write_record

addl $8, %esp            #回收空间

#关闭文件描述符

movl $SYS_CLOSE, %eax

movl $ST_FILE_DESCRIPTOR(%ebp), %ebx

int $LINUX_SYSCALL

#退出程序

movl $SYS_EXIT, %eax

movl $0, %ebx

int $LINUX_SYSCALL

程序说明:

1、.include "linux.s"表示应用文件,和C语言中的#include宏声明相同。

2、.rept和.endr为重复填充某个数据,需要指明填充次数、填充的数据类型、填充的值

3、编译、链接,执行:

as write-record.s -o write-record.o

as write-records.s -o write-records.o

ld write-record.o write-records.o -o write-records

执行:./write-records

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值