前言
这是一个汇编语言教程。32位。
会介绍如何使用串指令和使用循环指令来比较2个字符串是否相等。
两种方法共通的数据段
data segment
str1 db 'hello',0 ;定义一个名为str1的字符串'hello',以'/0'结尾
str2 db 'hello',0
result db ?
data ends
使用串指令
一些必要的初始化操作
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax
mov es,ax
lea si,str1
lea di,str2
mov cx,5
- assume cs:code,ds:data的作用是,将代码段和数据段的默认起始地址与相应的段寄存器关联。这样,程序中的指令和数据引用可以使用相对于这些默认段地址的偏移量来进行访问。
- 由于下面需要使用串指令,它的设定是使用si和di这两个寄存器,si对应es,di对应ds。所以需要把这两个段寄存器都定位到我们上面写的data段,以便程序可以正确地访问和操作数据段中的数据。
- lea si,str1 用si指向str1,str1这个标签实际上代表地址
- mov cx,5设置循环变量为5,约定使用cx寄存器存放
比较的逻辑部分
repe cmpsb
je equal
mov result,0
jmp toend
equal: mov result,1
- repe 即repeat if equal 比较结果相同就重复
- cmpsb 字符串比较,一个字节一个字节地比较
逻辑就是 ,一个字母一个字母地比较,如果遇到不同的,就退出比较,否则就比较到字符串末尾。接着查看比较结果,一样就跳转到赋结果为1的地方,否则就赋结果为0,然后跳转到程序末尾。
程序末尾
toend: mov ah,4ch
int 21h
code ends
end start
- mov ah, 4ch: 将值 4Ch 移动到寄存器 ah 中。在DOS环境下,4Ch 是DOS服务调用号,用于指示程序的退出。
- int 21h: 执行中断 21h,这是DOS中断服务例程的一部分。用于调用DOS功能, 4Ch 表示请求程序的退出。
综合起来,这两条指令的目的是告诉DOS运行时环境,程序执行完毕,请求正常退出,并将返回码(如果有的话)存储在 al 寄存器中。
使用手动比较指令
一些必要的初始化操作
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax
lea si,str1
lea di,str2
mov cx,5
dec si
dec di
- 少了mov es,ax,因为不使用串指令时的一般情况下,si,di这两个寄存器默认和ds绑定,不需要es寄存器了。
- 多了dec自减操作,这个需要结合下面循环里的自增,因为需要防止比较完了再指向下一个字母,这个自增操作会影响标志位寄存器,所以需要在比较前一开始就自增,要保持正确的比较就需要进入循环前自减1。
比较的逻辑部分
lop: inc si
inc di
mov ax,[si]
mov bx,[di]
cmp al,bl
loope lop
je equal
mov result,0
jmp toend
逻辑就是自增,比较,因为没办法2个内存地址的值直接比较,所以移到寄存器里。比较低位是因为,一个字母8位,ax是16位寄存器。其他逻辑一样。
程序末尾
toend: mov ah,4ch
int 21h
code ends
end start
完整代码
串指令版
data segment
str1 db 'hello',0
str2 db 'hello',0
result db ?
data ends
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax
mov es,ax
lea si,str1
lea di,str2
mov cx,5
repe cmpsb
je equal
mov result,0
jmp toend
equal: mov result,1
toend: mov ax,4ch
int 21h
code ends
end start
手动比较版
data segment
str1 db 'hello',0
str2 db 'hello',0
result db ?
data ends
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax
lea si,str1
lea di,str2
dec si
dec di
mov cx,5
lop: inc si
inc di
mov ax,[si]
mov bx,[di]
cmp al,bl
loope lop
je equal
mov result,0
jmp toend
equal: mov result,1
toend: mov ah,4ch
int 21h
code ends
end start