首页
社区
课程
招聘
[原创]汇编基础 课题7
发表于: 2008-3-12 22:31 9388

[原创]汇编基础 课题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

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
2
一二张图片为程序1的运行结果,三四五为程序2的程序结果,六为程序3的运行结果。
一为加载程序到内存中的源码,二为运行后的,其中00006H为C,即11B个数,CCFFH为X。
三为代码,四为数据段的100个字单元,以及0064H为数组长度;五为删除、压缩后的结果,只是有点模糊。
六为运行后的结果,可以看出(X)=0003H str="MOONMOONMOONF$',前面的03为str中“MOON”的个数。
2008-3-12 22:34
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
3
不错,学习。。。
2008-3-12 23:44
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
4
写的很清楚!
2008-3-13 09:06
0
雪    币: 397
活跃值: (372)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
5
LZ 认真,排版也好,学习~~~
2008-3-13 09:26
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习~~~ ....
2008-3-21 21:01
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
占位 有时间仔细学习下
2008-3-22 00:42
0
游客
登录 | 注册 方可回帖
返回
//