本篇主要针对以下结构型记录,编写程序进行处理。主要有:读数据操做、修改数据、写数据操做。每一个程序将分开书写。同时,本篇程序使用新技术,将几段代码分别存放在不一样文件中。linux
本程序包含三个部分:(1)将三个记录写入文件中函数
(2)显示文件中的记录编码
(3)将每一个记录中的年龄
spa
采用外文名字进行存储:名——40字节;姓——40字节;地址——240字节;年龄——4字节code
由以上结构,定义以下常量,并存于文件record-def.s文件中:ci
.equ RECORD_FIRSTNAME, 0 .equ RECORD_LASTNAME, 40 .equ RECORD_ADDRESS, 80 .equ RECORD_AGE, 320 .equ RECORD_SIZE, 324
如下为读取文件操做中经常使用的常数,存储在文件linux.s中:it
#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
下面函数放在read-record.s文件中
io
.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
下面函数放在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
具体步骤为:打开文件,写3条记录,关闭文件。输入如下代码到write-records.s文件中function
.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
一、.include "linux.s"表示应用文件,和C语言中的#include宏声明相同。
二、.rept和.endr为重复填充某个数据,须要指明填充次数、填充的数据类型、填充的值
三、编译、连接,执行:
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