汇编程序—将一个全是字母,以0结尾的字符串,转化为大写

程序思路

我们有一个现成的指令jcxz 可以判断cx寄存器中是否0,可以将data段的数据一个一个放到cx中,紧接着调用jcxz指令,如果cx为0 跳出子程序,如果不为0进行大写转化!
这里为了方便展示,将转换前后的字符串都放到屏幕中进行展示,代码中有一定的注释。

程序代码

assume cs:code,ss:stack

data segment
    db 'laymond',0
data ends
stack segment
    db 128 dup(0)
stack ends

code segment
    main:
    mov ax,stack
    mov ss,ax
    mov sp,128
    mov ax,data
    mov ds,ax

    call init_reg
    call clear_screen
    call show_1word



    mov ax,4c00H
    int 21H
;------------------------------
show_1word:
    mov si,0        ;si 为源字符串的位置
    mov di,160*10+40*2  ;显示在第10行中间位置
    call show_string    

    call to_upper       ;si to_upper参数,要转换字符串的起始位置

    mov di,160*11+40*2  ;di show_string参数,显示的地址,将其显示到下一行
    call show_string    
    ret
;------------------------------
;子程序功能 将字符串转换为大写
;参数寄存器 si 转换字符串的起始地址
to_upper:
    push cx
    push si 
toUpper:
    mov cx,0
    mov cl,ds:[si]      
    jcxz upperRet
    and byte ptr ds:[si],11011111B
    inc si
    jmp toUpper
upperRet:
    pop si
    pop cx
    ret
;------------------------------
;子程序功能 显示指定位置的字符串
;参数寄存器 si 源字符串的位置
;参数寄存器 di 字符串显示的位置
show_string:
        ;将使用到的寄存器变量通过栈保存,使用完毕将可通过弹栈数据还原
        push ax
        push cx
        push es
        push ds
        push di
        push si

        mov ax,0B800H
        mov es,ax
showLetter:
        mov cx,0
        mov cl,ds:[si]
        jcxz showRet
        mov al,ds:[si]      ;内存单元之间不能直接进行赋值!必须借助寄存器
        mov es:[di],al  
        inc si
        add di,2
        jmp showLetter
showRet:
        pop si
        pop di
        pop ds
        pop es
        pop cx
        pop ax
        ret
;------------------------------
init_reg:
        mov bx,0B800H   ;显存起始位置
        mov es,bx 
        ret
;-------------------------------
clear_screen:
        mov bx,0
        mov dx,0700H    ;黑底空字符,偶数字节为显示字符,奇数字节放显示方式
        mov cx,2000     ;每页25行,每行可显示80个字符,2000个字符,循环2000次
clearScreen:
        mov es:[bx],dx
        add bx,2
        loop clearScreen
        ret

code ends

end main

运行结果

这里写图片描述

题目扩展

如果是多行字符串转换呢?还是一样的,由于我们上面写代码是按功能写的子程序,那么进行扩展就非常方便了!

多行字符串代码

assume cs:code,ss:stack

data segment
    db 'aaaa',0
    db 'bbbb',0
    db 'cccc',0
    db 'dddd',0
data ends
stack segment
    db 128 dup(0)
stack ends

code segment
    main:
    mov ax,stack
    mov ss,ax
    mov sp,128
    mov ax,data
    mov ds,ax

    call init_reg
    call clear_screen
    call show_4word


    mov ax,4c00H
    int 21H
;------------------------------
show_4word:
    mov di,160*10+40*2  ;dos显存 每页2580字符/行,每个字符2个字节,从第10行开始显示
    mov si,0
    mov cx,4
show_word:

    call show_string    
    call to_upper
    call show_UpperString

    add di,160      ;显示到下一行,每行160字节
    add si,5        ;si 为to_upper参数 下一个字符串的起始位置

    loop show_word

    ret
show_UpperString:
    push di
    add di,20       ;di 为show_string参数 将大写后的字符串显示到 源字符串的后面
    call show_string    
    pop di
    ret 
;------------------------------
;子程序功能 将字符串转换为大写
;参数寄存器 si 转换字符串的起始地址
to_upper:
    push cx
    push si 
toUpper:
    mov cx,0
    mov cl,ds:[si]      
    jcxz upperRet
    and byte ptr ds:[si],11011111B
    inc si
    jmp toUpper
upperRet:
    pop si
    pop cx
    ret
;------------------------------
;子程序功能 显示指定位置的字符串
;参数寄存器 si 源字符串的位置
;参数寄存器 di 字符串显示的位置
show_string:
        ;将使用到的寄存器变量通过栈保存,使用完毕将可通过弹栈数据还原
        push ax
        push cx
        push es
        push ds
        push di
        push si

        mov ax,0B800H
        mov es,ax
showLetter:
        mov cx,0
        mov cl,ds:[si]
        jcxz showRet
        mov al,ds:[si]      ;内存单元之间不能直接进行赋值!必须借助寄存器
        mov es:[di],al  
        inc si
        add di,2
        jmp showLetter
showRet:
        pop si
        pop di
        pop ds
        pop es
        pop cx
        pop ax
        ret
;------------------------------
init_reg:
        mov bx,0B800H   ;显存起始位置
        mov es,bx 
        ret
;-------------------------------
clear_screen:
        mov bx,0
        mov dx,0700H    ;黑底空字符,偶数字节为显示字符,奇数字节放显示方式
        mov cx,2000     ;每页25行,每行可显示80个字符,2000个字符,循环2000次
clearScreen:
        mov es:[bx],dx
        add bx,2
        loop clearScreen
        ret

code ends

end main

多行字符串运行结果

猜你喜欢

转载自blog.csdn.net/qq_29542611/article/details/80960938
今日推荐