这个程序,主要是应用标志寄存器和其他的一些语法练习,希望能够给大家一点点帮助。
;标志寄存器:
;功能:标志寄存器是CPU对每句代码对数据执行的操作进行保存,以方便下面代码对程序的运行方向进行修改
;信息:标志寄存器和其他寄存器一样十六位,其标志位信息如下表所示:
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
; CF PF AF ZF SF TF IF DF OF
;代表含义:
;OF overflow flag 溢出标志 操作数超出机器能表示的范围表示溢出,溢出时为1.
;SF sign Flag 符号标志 记录运算结果的符号,结果负时为1.
;ZF zero flag 零标志 运算结果等于0时为1,否则为0.
;CF carry flag 进位标志 最高有效位产生进位时为1,否则为0.
;AF auxiliary carry flag 辅助进位标志 运算时,第3位向第4位产生进位时为1,否则为0.
;PF parity flag 奇偶标志 运算结果操作数位为1的个数为偶数个时为1,否则为0.
;DF direcion flag 方向标志 用于串处理.DF=1时,每次操作后使SI和DI减小.DF=0时则增大.
;IF interrupt flag 中断标志 IF=1时,允许CPU响应可屏蔽中断,否则关闭中断.
;TF trap flag 陷阱标志 用于调试单步操作.
;
;相关命令:
; pushf 标志寄存器入栈
; popf 标志寄存器出栈
; cmp 比较指令,仅影响标志位,不保存结果
; adc 带进位加法
; sbb 带进位减法
; je 等于则跳
; jne 不等则跳
; jb 低于则跳
; jnb 不低于则跳
; ja 高于则跳
; jna 不高于则跳
;编写程序,对数据区的数据大小写反转,并保存在后面的零区域中
;大写ASCII码 A-Z(65-90),小写ASCII码 a-z(97-122)
assume cs:code,ds:data,ss:stack
code segment
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,64 ;设置相关寄存器
mov cx,20 ;设置循环标志
s:
mov bx,cx
mov ax,0
mov al,byte ptr ds:[bx] ;读出字符
push ax ;参数入栈
call _state ;调用状态函数判断大小写
add sp,2 ;平衡堆栈
cmp ax,0 ;靠状态函数的返回值来判断跳转,首先判断是否为小写
je xiao ;转至小写修改代码
cmp ax,1 ;判断是否大写
je da ;转至大写修改代码
cmp ax,0ffh ;判断数据是否出错
je ove ;转至结束处
xiao:
push bx ;参数入栈
call _ToCaptital ;字符为小写,调用_ToCaptital函数转为大写
add sp,2 ;平衡堆栈
jmp ove
da:
push bx ;参数入栈
call _toLower ;字符为大写,调用_toLower函数转为小写
add sp,2 ;平衡堆栈
ove:
dec cx ;循环标志自减
cmp cx,0ffh ;比较循环标志是否为-1
je exit ;如为-1则跳出循环
jmp s ;继续循环
exit:
mov ax,4c00h
int 21h
;功能:判断ASCII码大小写
;参数:ASCII码值
;返回值:AL中1为大写,0为小写,FF为出错
_state:
push bp
pushf
mov bp,sp ;保存要使用的相关寄存器
mov ax,ss:[bp + 6] ;读入字符的ASCII码,注意参数在堆栈中的位置,CALL指令只含有一个字
cmp ax,97
je xiaoxie
ja xiaoxie ;ASCII码大于等于97,为小写,否则为大写
cmp ax,90 ;ASCII码和90做比较,用于比较ASCII码是否大于90
ja _excption ;ASCII码大于90则数据错误
cmp ax,65 ;ASCII码和65做比较,用于比较ASCII码是否大于65,大写ASCII码范围应为65-90
jb _excption ;小于65则数据错误
mov al,1 ;设置返回值为1,表大写
jmp short over ;跳至进程结束
xiaoxie:
cmp ax,122 ;判断ASCII码是否小于122,即小写的范围应该是97-122
ja _excption ;判断ASCII码是否大于122,大于则出错
mov al,0 ;设置返回值内容为0,表示小写
over:
popf
pop bp ;恢复相关寄存器
ret
;功能:转大写
;参数:ASCII码内存地址
;返回值:无
_ToCaptital:
push bp
push bx
push ax
pushf
mov bp,sp
mov bx,word ptr ss:[bp + 10] ;读入参数
mov al,byte ptr ds:[bx] ;读入该地址的ASCII码
and al,11011111B ;将该ASCII码变为大写
mov byte ptr ds:[bx],al ;修改内存数据
popf
pop ax
pop bx
pop bp
ret
;功能:转小写
;参数:ASCII码内存地址
;返回值:无
_toLower:
push bp
push bx
push ax
pushf
mov bp,sp
mov bx,word ptr ss:[bp + 10] ;读入参数
mov al,byte ptr ds:[bx] ;读入该地址的ASCII码
or al,00100000B ;将该ASCII码变为大写
mov byte ptr ds:[bx],al ;修改内存数据
popf
pop ax
pop bx
pop bp
ret
;功能:异常处理,处理方式为子程序直接返回
;参数:无
;返回值:无
_excption:
popf
pop bp ;恢复相关寄存器
mov al,0ffh ;设置返回值为出错
ret
code ends
data segment
db 'Wel5lCoMe T4o M3aSm2!'
data ends
stack segment
dw 32 dup(0)
stack ends
end start