32位汇编语言学习笔记(23)--大小写转换程序2

来源:互联网 发布:数控切割直板怎么编程 编辑:程序博客网 时间:2024/06/05 04:19

上一篇的大小写转换程序效率比较低,每读入一个字节就会做一次系统调用,如下是一个快速版本的大小写转换程序。

SECTION .bss                    ; Section containing uninitialized data

        BUFFLEN equ 1024;Length of buffer

        Buff:      resb BUFFLEN ; Text buffer itself

SECTION .data                           ; Section containing initialised data

SECTION .text                   ; Section containing code

global    _start                         ; Linker needs this tofind the entry point!

_start:

        nop                    ; This no-op keeps gdbhappy...

; Read a buffer full of text from stdin:

read:

        moveax,3                 ; Specify sys_readcall

        movebx,0                 ; Specify FileDescriptor 0: Standard Input

        movecx,Buff            ; Pass offset of thebuffer to read to

        movedx,BUFFLEN            ; Pass number ofbytes to read at one pass

        int80h                       ; Call sys_readto fill the buffer

        movesi,eax              ; Copy sys_readreturn value for safekeeping

        cmpeax,0                 ; If eax=0,sys_read reached EOF on stdin

        jleDone            ; Jump If equal or below(to 0, from compare)

; Set up the registers for the processbuffer step:

        movecx,esi              ; Place the number ofbytes read into ecx

; Go through the buffer and convertlowercase to uppercase characters:

Scan:

        cmpbyte [Buff-1+ecx],61h      ; Test inputchar against lowercase 'a'

        jbNext                       ; If below 'a'in ASCII, not lowercase

        cmpbyte [Buff-1+ecx],7Ah     ; Test inputchar against lowercase 'z'

        jaNext                       ; If above 'z'in ASCII, not lowercase

                                    ;At this point, we have a lowercase char

        subbyte [Buff-1+ecx],20h       ; Subtract20h to give uppercase...

Next:       dececx                      ; Decrementcounter

        jnzScan            ; If characters remain,loop back

; Write the buffer full of processed textto stdout:

Write:

        moveax,4                 ; Specify sys_writecall

        movebx,1                 ; Specify FileDescriptor 1: Standard output

        movecx,Buff            ; Pass offset of thebuffer

        movedx,esi              ; Pass the # ofbytes of data in the buffer

        int80h                       ; Make kernelcall

        jmpread          ; Loop back and loadanother buffer full

; All done! Let's end this party:

Done:

        moveax,1                 ; Code for ExitSyscall

        movebx,0                 ; Return a code ofzero   

        int80H                       ; Make kernelcall


BUFFLEN equ1024; Length of buffer

Buff:      resb BUFFLEN

Buff在装载时预留了1024字节的空间。

mov esi,eax

sys_read系统调用的返回结果保存到esi

sys_read返回值如果是0,表示读取文件结束(遇到了EOF),大于0表示读入的字节数,如果小于0表示出错。

mov ecx,esi

esi装入的是sys_read系统调用的返回值,所以ecx也保存了这个返回值,此时ecx中的值是大于0的,表示读入的字节数。

Scan标号到Write标号之前是进行循环,扫描Buffer的内容,如果大于等于’a’,小于等于’z’,就进行大小写转换,循环的次数就是读入的字节个数。

makefile文件如下:

uppercaser2: uppercaser2.o

        ld-o uppercaser2 uppercaser2.o

uppercaser2.o: uppercaser2.asm

        nasm-f elf -g -F stabs uppercaser2.asm

[root@bogon uppercaser2]# ./uppercaser2> output.txt < uppercaser2.asm

打开output.txt文件可以看到完成了大小写转换操作。




0 0