本篇主要針對以下結構型記錄,編寫程序進行處理。主要有:讀數據操做、修改數據、寫數據操做。每一個程序將分開書寫。同時,本篇程序使用新技術,將幾段代碼分別存放在不一樣文件中。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