我发现了一个名为:ProgrammingGroundUp-1-0-booksize.pdf的pdf文件,其中一个项目是制作一个汇编程序,它接收文件并将它们转换为大写,
.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页,如果你在谷歌上查找它你很容易得到,也因为某些原因代码没有正确复制和粘贴,所以你有时可能会看到例如:jmp to_another_point
我试图摆脱尽可能多的那些,但仍然可能有一些,并且一些评论可能在此过程中丢失,所以我建议打开原始的pdf文件.我正在运行Ubuntu linux版本10.04.1,我使用的是版本2.20.1,问题是它创建了文件,但文件始终为空.
本书的源代码是可用的,如果您浏览CVS存储库的相应部分,您可以找到.s
各种示例的源文件.
这段代码是toupper.s
- 你可以下载最新的版本,而不是乱搞复制和粘贴.
我只是去尝试(在Debian系统上,我没有什么运行Ubuntu 10.04手),组装和书中描述的准确连接,它工作得很好.