汇编学习笔记->比较两字符串是否相等

emu8086
ASCII表中13表示回车->回到该行的首部。10表示换行->光标在行中的位置不变,移动到下一行

datas   segment
    string1 db  'Move the cursor backward'  
    string2 db  'Move the cursor backward'
    
    mess1   db  'Match.',13,10,'$'      ;13是回车符,10是换行符的ASCII码,$是字符串结束的标志
    mess2   db  'No match',13,10,'$'     
datas   ends

codes   segment
    assume cs:codes ,ds:datas   ,es:datas 
start:
main    proc    far
    push    ds                          ;将ds压栈
    sub     ax,ax                       ;将ax置0
    push    ax                          ;0入栈
    ;push   ds
    ;mov    ax,0
    ;push   ax
    ;……
    ;ret
    ;上述指令时配对出现的,和中断调用mov ax 4c00h/int 21h功能相似,实现返回DOS系统的操作
    ;原理:作为DOS系统,每个EXE文件在执行时被看作DOS的一个子程序,所以有子程序的入口
    ;此时EXE文件的入口地址CS值和DS值相同,而IP值等于0,所以前面的push ds相当于cs入栈
    ;而把AX赋0然后入栈,相当于IP入栈。这样当程序最后再执行ret后,就可以返回原DOS系统了
    mov     ax,datas                    
    mov     ds,ax
    mov     es,ax                       ;拷贝到附加段
    
    ;load effective address 加载有效地址
    lea     si,string1                  ;将string1的有效地址存储到si寄存器中
    lea     di,string2                  ;同上
    cld                                 ;在字符串操作中使变址寄存器SI和DI的地址指针自动增加,字符串处理由前往后
    mov     cx,25                       ;字符串的长度为25,比较25次
    repz    cmpsb                       ;如果DS:si和ES:di所指向的两个字节相等则继续比较
    ;repeat when zero flag ZF为0时重复
    jz      match                       ;jump when has zero flag,完全匹配时ZF=1,即上一条指令运算结果为0,则跳转    
    lea     dx,mess2                    ;jz没有跳转,将No match字符串存储到寄存器dx中
    jmp     short disp                  ;段内短跳转
match:
    lea     dx,mess1                    ;将Match字符串存储到寄存器dx中
disp:
    mov     ah,09                       ;dos系统功能调用代码→显示字符串 DS:DX=串地址,字符串以$结尾
    int     21H                         ;调用dos系统功能,计算机会根据AH寄存器中的值调用相应功能 P471
    ret                                 ;栈顶字单元出栈,其值赋给IP寄存器,实现程序的转移
main endp
codes ends
end start   

一些指令的解释

代码段

push ds
mov ax,0
push ax
……
ret
上述指令时配对出现的,和中断调用mov ax 4c00h/int 21h功能相似,实现返回DOS系统的操作
原理:作为DOS系统,每个EXE文件在执行时被看作DOS的一个子程序,所以有子程序的入口。此时EXE文件的入口地址CS值和DS值相同,而IP值等于0,所以前面的push ds相当于cs入栈。而把AX赋0然后入栈,相当于IP入栈。这样当程序最后再执行ret后,就可以返回原DOS系统了

cmpsb指令

该指令会取出DS:SI和ES:DI所指向的字节进行比较,如果相等则符号位ZF置1。配合repz(repeat when zero flag)指令使用时,当 ZF=1 且 CX!=0 时会重复cmpsb指令

repz指令

当ZF=1 且 CX!=0时则重复

movsb指令的前面只能使用rep前缀,不用repz或repnz前缀,因为movs指令执行后不影响zf标志位。
换句话说,就是在movsb指令的前面使用3个前缀的功能是一样的,结束movsb指令只受CX取值的控制,与ZF无关
验证:
你将ZF标志位设置为1,你执行REPNZ MOVSB指令看,一样的,只受CX取值的控制,与ZF无关。

附:end start表示整个代码文件的结束,此时不论在end start的后边加什么内容,软件都不会将其编译。

发布了19 篇原创文章 · 获赞 2 · 访问量 4197

猜你喜欢

转载自blog.csdn.net/c529283955/article/details/102971044
今日推荐