如何在Linux中制作一个x86汇编程序,将文件转换为大写? [英] how do you make an x86 assembly program in linux that converts files to uppercase?

查看:71
本文介绍了如何在Linux中制作一个x86汇编程序,将文件转换为大写?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一个名为:ProgrammingGroundUp-1-0-booksize.pdf的pdf文件,其中一个项目是制作一个汇编程序,该程序将文件吸收并将其转换为大写字母,

I found a pdf file called: ProgrammingGroundUp-1-0-booksize.pdf, and one of the projects is to make an assembly program that takes in files and converts them to uppercase, `

.section .data
#######CONSTANTS########
#system call numbers
.equ SYS_OPEN, 5
.equ SYS_WRITE, 4
.equ SYS_READ, 3
.equ SYS_CLOSE, 6
.equ SYS_EXIT, 1
#options for open (look at
#/usr/include/asm/fcntl.h for
#various values. You can combine them
#by adding them or ORing them)
#This is discussed at greater length
#in "Counting Like a Computer"
.equ O_RDONLY, 0
.equ O_CREAT_WRONLY_TRUNC, 03101
#standard file descriptors
.equ STDIN, 0
.equ STDOUT, 1
.equ STDERR, 2
#system call interrupt
.equ LINUX_SYSCALL, 0x80
.equ END_OF_FILE, 0
#This is the return value
#of read which means we’ve
#hit the end of the file
.equ NUMBER_ARGUMENTS, 2
.section .bss
.equ BUFFER_SIZE, 500
.lcomm BUFFER_DATA, BUFFER_SIZE
.section .text
#STACK POSITIONS
.equ ST_SIZE_RESERVE, 8
.equ ST_FD_IN, -4
.equ ST_FD_OUT, -8
.equ ST_ARGC, 0
#Number of arguments
.equ ST_ARGV_0, 4
#Name of program
.equ ST_ARGV_1, 8
#Input file name
.equ ST_ARGV_2, 12
#Output file name
.globl _start
_start:
###INITIALIZE PROGRAM###
#save the stack pointer
movl %esp, %ebp
#Allocate space for our file descriptors
#on the stack
subl $ST_SIZE_RESERVE, %esp
open_files:
open_fd_in:
###OPEN INPUT FILE###
#open syscall
movl $SYS_OPEN, %eax
#input filename into %ebx
movl ST_ARGV_1(%ebp), %ebx
#read-only flag
movl $O_RDONLY, %ecx
#this doesn’t really matter for reading
movl $0666, %edx
#call Linux
int $LINUX_SYSCALL
store_fd_in:
#save the given file descriptor
movl %eax, ST_FD_IN(%ebp)
open_fd_out:
###OPEN OUTPUT FILE###
#open the file
movl $SYS_OPEN, %eax
#output filename into %ebx
movl ST_ARGV_2(%ebp), %ebx
#flags for writing to the file
movl $O_CREAT_WRONLY_TRUNC, %ecx
#mode for new file (if it’s created)
movl $0666, %edx
#call Linux
int
$LINUX_SYSCALL
store_fd_out:
#store the file descriptor here
movl %eax, ST_FD_OUT(%ebp)
###BEGIN MAIN LOOP###
read_loop_begin:
###READ IN A BLOCK FROM THE INPUT FILE###
movl $SYS_READ, %eax
#get the input file descriptor
movl ST_FD_IN(%ebp), %ebx
#the location to read into
movl $BUFFER_DATA, %ecx
#the size of the buffer
movl $BUFFER_SIZE, %edx
#Size of buffer read is returned in %eax
int
$LINUX_SYSCALL
###EXIT IF WE’VE REACHED THE END###
#check for end of file marker
cmpl $END_OF_FILE, %eax
#if found or on error, go to the end
jle end_loop
continue_read_loop:
###CONVERT THE BLOCK TO UPPER CASE###
pushl $BUFFER_DATA
#location of buffer
pushl %eax
#size of the buffer
call convert_to_upper
popl %eax
#get the size back
addl $4, %esp
#restore %esp
###WRITE THE BLOCK OUT TO THE OUTPUT FILE###
#size of the buffer
movl %eax, %edx
movl $SYS_WRITE, %eax
#file to use
movl ST_FD_OUT(%ebp), %ebx
#location of the buffer
movl $BUFFER_DATA, %ecx
int $LINUX_SYSCALL
###CONTINUE THE LOOP###
jmp read_loop_begin
end_loop:
###CLOSE THE FILES###
#NOTE - we don’t need to do error checking
movl $SYS_CLOSE, %eax
movl ST_FD_OUT(%ebp), %ebx
int $LINUX_SYSCALL
movl ST_FD_IN(%ebp), %ebx
movl $SYS_CLOSE, %eax
int $LINUX_SYSCALL
###EXIT###
movl $SYS_EXIT, %eax
movl $0, %ebx
int $LINUX_SYSCALL
###CONSTANTS##
#The lower boundary of our search
.equ LOWERCASE_A, ’a’
#The upper boundary of our search
.equ LOWERCASE_Z, ’z’
#Conversion between upper and lower case
.equ UPPER_CONVERSION, ’A’ - ’a’
###STACK STUFF###
.equ ST_BUFFER_LEN, 8 #Length of buffer
.equ ST_BUFFER, 12
#actual buffer
convert_to_upper:
pushl %ebp
movl %esp, %ebp
###SET UP VARIABLES###
movl ST_BUFFER(%ebp), %eax
movl ST_BUFFER_LEN(%ebp), %ebx
movl $0, %edi
#if a buffer with zero length was given
#to us, just leave
cmpl $0, %ebx
je end_convert_loop
convert_loop:
#get the current byte
movb (%eax,%edi,1), %cl
#go to the next byte unless it is between
#’a’ and ’z’
cmpb $LOWERCASE_A, %cl
jl next_byte
cmpb $LOWERCASE_Z, %cl
jg next_byte
#otherwise convert the byte to uppercase
addb $UPPER_CONVERSION, %cl
#and store it back
movb %cl, (%eax,%edi,1)
next_byte:
incl %edi
#next byte
cmpl %edi, %ebx
#continue unless
#we’ve reached the
#end
jne convert_loop

end_convert_loop:
#no return value, just leave
movl %ebp, %esp
popl %ebp
ret
`

汇编器称为"as",代码在文件的第87页上,如果您在google上查找该代码,则很容易得到,并且由于某些原因该代码无法正确复制和粘贴,因此您有时可能会看到类似以下内容:跳to_another_point

the assembler is called "as", and the code is on page 87 of the file, you can easily get if you look it up on google, also the code doesn't copy and paste correctly for some reason, so you might sometimes see things like: jmp to_another_point

我尽力摆脱了所有这些,但是可能仍然有一些,在此过程中一些注释可能丢失了,所以我建议打开原始的pdf文件.我正在运行Ubuntu Linux 10.04.1版,我正在使用2.20.1版,问题是它创建了文件,但文件始终为空.

I tried to get rid of as many of those as I could, but there still might be some, and some of the comments were probably lost in the process, so I would suggest opening the original pdf file. I am running Ubuntu linux version 10.04.1, I am using as version 2.20.1, and the problem is that it creates the file, but the file is always empty.

推荐答案

此书的源可用,如果您浏览CVS存储库的相应部分,您可以找到各种示例的 .s 源文件.

The source for this book is available, and if you browse the appropriate part of the CVS repository you can find .s source files for the various examples.

此代码为 toupper.s -您只需下载最新的修订版本,而不必搞乱复制和粘贴.

This code is toupper.s - you can just download the most recent revision instead of messing around with copy-and-paste.

我刚刚尝试过(在Debian系统上;我没有运行Ubuntu 10.04的任何东西),完全按照书中的描述进行组装和链接,并且效果很好.

I've just tried that (on a Debian system; I don't have anything running Ubuntu 10.04 to hand), assembling and linking exactly as described in the book, and it worked fine.

这篇关于如何在Linux中制作一个x86汇编程序,将文件转换为大写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆