【Linux x86汇编踩坑】文件读写(二)读取文件转换大小写
2018-01-22 11:12
357 查看
【Linux x86汇编踩坑】文件读写(二)读取文件转换大小写
前言
转换大小写的思路很简单,来尝试用汇编写一个转换大小写的程序吧转换大小写
由于在汇编中字符也是用ascii码存储的,那么思路就很清晰了,比如a对应的ascii码是97,而A对应的ascii码是65,那么将a转换为A只需要让a +(-32)即可,这个-32是他们之间的差,由于字母之间的ascii码是连续的,那么从a-z的小写字母我们都可以让它们加上-32来转换为大写字母。知道了实现原理之后我们来实现一下这个函数。
#转换大小写 .type upperConversion, @function #确定需要转换的字符的上下界限 .equ UP_CRITICAL, 'z' .equ LOWER_CRITICAL, 'a' #转换需要相加的数 .equ UPPER_CONVERSION, 'A' - 'a' upperConversion: pushl %ebp movl %esp, %ebp movl $BUFFER_SIZE, %ebx #如果给定的缓冲区的长度为0 cmpl $0, %ebx je conversion_exit #索引 movl $0, %edi #读取字节 read_byte: movb BUFFER_DATA(,%edi,1), %cl cmpb $UP_CRITICAL, %cl jg next_byte cmpb $LOWER_CRITICAL, %cl jl next_byte #转换大小写 addb $UPPER_CONVERSION, %cl movb %cl, BUFFER_DATA(,%edi,1) next_byte: incl %edi cmpl %edi, %ebx jne read_byte conversion_exit: popl %ebp ret
需要注意的是,BUFFER_DATA和BUFFER_SIZE分别对应我申请的缓冲区大小和缓冲区长度,具体代码在【Linux x86汇编踩坑】文件读写(一)读取文件并输出中,下面我也会附上完整的代码。
整体来看,上述代码用了一个循环read_byte来循环读取缓冲区里的字节,判断是否在a-z的范围内:
cmpb $UP_CRITICAL, %cl jg next_byte cmpb $LOWER_CRITICAL, %cl jl next_byte
如果在范围内则进行转换大小写的操作,也就是给小写字母加上-32,然后将转换后的字符覆盖到原来缓冲区的位置
addb $UPPER_CONVERSION, %cl movb %cl, BUFFER_DATA(,%edi,1)
如果在a-z的范围内,也就是不属于小写字母了,那么我们可以跳过,直接读取下一个字符
next_byte: incl %edi cmpl %edi, %ebx jne read_byte
conversion_exit标签用于结束整个函数,把ebp弹出栈,通过ret把把函数返回地址弹出,随后eip寄存器指向函数的返回地址。
conversion_exit: popl %ebp ret
整个过程还是比较简单的,下面我附上完整的代码,整个程序的功能主要是读取一个文件的所有字符,并将小写字符转换为大写字符后进入标准输出流输出
toupper.s
.section .data
#系统调用号
.equ SYS_EXIT, 1
.equ SYS_READ, 3
.equ SYS_WRITE, 4
.equ SYS_OPEN, 5
.equ SYS_CLOSE, 6
#文件打开选项
.equ FILE_READONLY, 0
.equ FILE_WRITE, 03101
#系统调用中断
.equ SYS_INTERRUP, 0x80
#标准文件描述符
.equ STD_IN, 0
.equ STD_OUT, 1
.equ STD_ERR, 2
#文件结束符
.equ END_OF_FILE, 0
.section .bss
#申请缓冲区20byte
.equ BUFFER_SIZE, 50
.lcomm BUFFER_DATA, BUFFER_SIZE
.section .text
.globl _start
_start:
#文件名入栈
movl %esp, %ebp
pushl 8(%ebp)
# 打开文件
call openFile
addl $4, %esp
# 文件描述符保存在%eax
pushl %eax
# 读取文件
call readFile
addl $4, %esp
#转换大小写
call upperConversion
call writeFile
movl %eax, %ebx
movl $SYS_EXIT, %eax
int $SYS_INTERRUP
#系统调用打开文件
.type openFile, @function
openFile:
pushl %ebp
movl %esp, %ebp
#系统调用号
movl $SYS_OPEN, %eax
#文件名
movl 8(%ebp), %ebx
#读写意图
movl $FILE_READONLY, %ecx
#系统权限
movl $0666, %edx
#系统中断
int $SYS_INTERRUP
popl %ebp
ret
#读取文件
.type readFile, @function
readFile:
pushl %ebp
movl %esp, %ebp
read_loop:
#文件描述符
movl 8(%ebp), %ebx
#系统调用号
movl $SYS_READ, %eax
#缓冲区
movl $BUFFER_DATA, %ecx
#缓冲区大小
movl $BUFFER_SIZE, %edx
#系统调用
int $SYS_INTERRUP
cmpl $END_OF_FILE, %eax
jle loop_exit
jmp read_loop
#读取完毕
loop_exit:
#关闭文件
movl $SYS_CLOSE, %eax
movl 8(%ebp), %ebx
int $SYS_INTERRUP
popl %ebp
ret
#写入文件
.type writeFile, @function
writeFile:
pushl %ebp
movl %esp, %ebp
#文件描述符
movl $1, %ebx
#系统调用号
movl $SYS_WRITE, %eax
#缓冲区
movl $BUFFER_DATA, %ecx
#缓冲区大小
movl $BUFFER_SIZE, %edx
#系统调用
int $SYS_INTERRUP
popl %ebp
ret
#转换大小写 .type upperConversion, @function #确定需要转换的字符的上下界限 .equ UP_CRITICAL, 'z' .equ LOWER_CRITICAL, 'a' #转换需要相加的数 .equ UPPER_CONVERSION, 'A' - 'a' upperConversion: pushl %ebp movl %esp, %ebp movl $BUFFER_SIZE, %ebx #如果给定的缓冲区的长度为0 cmpl $0, %ebx je conversion_exit #索引 movl $0, %edi #读取字节 read_byte: movb BUFFER_DATA(,%edi,1), %cl cmpb $UP_CRITICAL, %cl jg next_byte cmpb $LOWER_CRITICAL, %cl jl next_byte #转换大小写 addb $UPPER_CONVERSION, %cl movb %cl, BUFFER_DATA(,%edi,1) next_byte: incl %edi cmpl %edi, %ebx jne read_byte conversion_exit: popl %ebp ret
在运行整个程序之前,先来编辑一下需要转换大小写的文件data,在data里写上这么一句,很简单的字符串对吧
hello world, MAN
尝试一下
as toupper.s -o toupper.o ld toupper.o -o toupper ./toupper data HELLO WORLD, MAN
successful!!!
相关文章推荐
- 【Linux x86汇编踩坑】文件读写(一)读取文件并输出
- linux 文件读写 读取文件大小
- 例说linux内核与应用数据通信(三):读写内核设备驱动文件
- Linux系统修改文件读写权限chmod、所有者或组chown
- Linux系统下如何查看及修改文件读写权限
- linux 循环读取文件的每一行
- Linux下各种主要文件系统的读写性能测试 ------------实际系统中的Nand Flash速度测试结果
- linux下c语言 读取文件
- windows和linux下读取文件乱码的终极解决办法!
- linux 读写文件
- Linux压缩文件的读取
- Linux 文件读写
- Linux读取文件到jsoncpp
- Linux下常用设置文件和文件夹读写权限操作
- linux下大文件读写源码示例
- linux下文件的读写操作
- C++ 读写文件实例总结 (StringToken 为单位读取 以及char为单位读取)
- Linux文件读写机制及优化方式
- Linux系统下如何查看及修改文件读写权限
- 15 Linux更改权限解决新建用户不能读写创建文件/文件夹的问题