-
-
[原创]汇编基础 课题7
-
发表于:
2008-3-12 22:31
9388
-
assume cs:code,ds:data,ss:stack
data segment
c dw 0 ;计数器,存储X中11B的个数
x dw 0ccff ;待计算11B的个数的参数
data ends
stack segment
dw 64 dup(0)
stack ends
code segment
start:
mov ax,data
mov ds,ax ;初始化数据段
mov ax,stack ;初始化堆栈段
mov ss,ax
mov sp,128
call Count ;调用子程序计算11B的个数
mov ax,4c00h ;返回
int 21h
Count proc near
push ax ;保护在子程序中要使用的寄存器
push bx
push cx
mov c,0 ;初始化计数器为0
mov cx,8 ;设置循环次数为8,因一个字单元可分为8个“四分之一字节”
mov bx,c000h ;0c00h=1100 0000 0000 0000b,即从左到右始每次测试二位,直到bx移至为0
s:
mov ax,x ;(AX)=X
and ax,bx ;测试AX中的某二位是否为11B
cmp ax,bx ;比较是否为11B
jz counter ;如果为11B,跳转到counter处使计数器C加1
jmp s1 ;比较不为11B,直接跳过inc c
counter:
inc c
s1:
push cx ;由于使用cl作移动位数寄存器,因此先保存一下
mov cl,2 ;设置向右移动两位
shr bx,cl ;(BX)向右移动两位,即如果(BX)=1100 0000 0000 0000B,则移动后为(BX)=0011 0000 0000 0000B
pop cx ;恢复CX内容
loop s ;如果(CX)=(CX)-1不为0,则返回开始循环处
pop cx ;恢复各个寄存器
pop bx
pop ax
ret ;返回函数调用处,严格来说这个算不上是真正的函数,但为了好听点,就叫它函数吧
Count endp
code ends
end start
assume cs:code,ds:data,ss:stack
data segment
c dw 0 ;计数器,存储字符串中“MOON”的个数
str db 'MOONMOONMOONF','$' ;待求字符串,传说中的数组,不过这里是以'$'结束的
data ends
stack segment
dw 16 dup(0)
stack ends
code segment
start:
mov ax,data ;初始化数据段和堆栈
mov ds,ax
mov ax,stack
mov ss,ax
mov cx,0 ;初始化计数器为0
call Count ;调用子程序计算字符串中“MOON”的个数,结果存储在C中
mov ah,4ch ;返回
int 21h
Count proc near
push si ;保护一下SI的内容,因下面要使用到它
mov si,0 ;初始化数组下标SI为0
s2:
cmp byte ptr str[si],'$' ;以下连续比较四个字符中是否有'$',因为后面0~4个字符之中如果有'$',则不必再检测是为为四个字符为“MOON”,经我反汇编查看了一下WIN-TC输出的汇编源码,我发现我写的这个检测方法要比它编译的稍微好一点点.如果没检测到’$',则继续往下检测这四个字符是否为“MOON”,否则跳到S3处结束循环
jz s3
cmp byte ptr str[si+1],'$'
jz s3
cmp byte ptr str[si+2],'$'
jz s3
cmp byte ptr str[si+3],'$'
jz s3
cmp byte ptr str[si],'M' ;比较字符串str中是当前下标指向的及后面的字符是否为“MOON”,如果Y,则继续往下执行,否则返回S2处执行
jnz s2
cmp byte ptr str[si+1],'O'
jnz s2
cmp byte ptr str[si+2],'O'
jnz s2
cmp byte ptr str[si+3],'N'
jnz s2
inc c ;如果运行到这里,则说明在str中检测到了一个"MOON"
add si,4 ;(SI)=(SI)+4,指针指向字符串后四个字符的开始处
jmp s2 ;进入下一轮检测
s3:
pop si ;恢复SI
ret ;返回函数调用处
Count endp
code ends
end start
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!