以下是汇编实验三的代码
第一个
DATA SEGMENT
WELCOME DB "Please input your string: ",'$' ;26个
STR DB 12
DB ?
DB 12 DUP(0)
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
LEA SI,WELCOME
MOV DX,SI
MOV AH,09H
INT 21H ;输出welcome字符
MOV DL,0DH ;输出的时候,输出dl的内容
MOV AH,02H ;输出回车
INT 21H
MOV DL,0AH ;0ah是换行
MOV AH,02H ;输出换行
INT 21H
LEA DX,STR
MOV AH,0AH
INT 21H ;输入str字符串
MOV DL,0DH ;输出的时候,输出dl的内容
MOV AH,02H ;输出回车
INT 21H
MOV DL,0AH ;0ah是换行
MOV AH,02H ;输出换行
INT 21H
MOV AL,STR+1 ;字符串个数
MOV CL,AL
ADD AL,2
MOV AH,0
MOV SI,AX
MOV STR[SI],'$' ;把$送到字符串末尾
LEA SI,STR+2
MOV AL,'&' ; 把判断&放到al中
XOR BX,BX
MOV BL,49
JMP BEGIN
CHANGE: MOV BYTE PTR [SI],' '
MOV DX,BX
MOV AH,02H
INT 21H
MOV DL,32
MOV AH,02H
INT 21H
MOV AH,0
MOV AL,'&'
BEGIN: CMP AL,[SI] ;使用cmp判断
JZ CHANGE ;判断零位,跳转change
INC SI
INC BX
LOOP BEGIN
MOV DL,0DH ;输出的时候,输出dl的内容
MOV AH,02H ;输出回车
INT 21H
MOV DL,0AH ;0ah是换行
MOV AH,02H ;输出换行
INT 21H
LEA DX,STR+2
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
使用了循环,指针定位。判断方法是一个个字符比较判断。
第二个
DATA SEGMENT
STR1 DB 512 DUP('$')
LEN EQU $-STR1
STR2 DB 512 DUP('$')
TRUE DB 'YES$'
FALSE DB 'NO$'
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV ES,AX ;设置附加段
;MOV CX,LEN ;设置循环位
MOV DI,OFFSET STR1 ;DI保存str1的偏移地址
MOV SI,OFFSET STR2 ;SI保存str2的偏移地址
MOV DX,OFFSET STR1
MOV AH,0AH ;输入str1
INT 21H
MOV DL,0DH ;回车换行
MOV AH,02H
INT 21H
MOV DL,0AH
MOV AH,02H
INT 21H
MOV DX,OFFSET STR2 ;输入第二个字符
MOV AH,0AH
INT 21H
MOV DL,0DH ;回车换行
MOV AH,02H
INT 21H
MOV DL,0AH
MOV AH,02H
INT 21H
CLD
MOV CX,LEN
REPZ CMPSB ;进行串操作比较
JZ MATCH ;比较置零位,为0
JNZ NOMATCH ;为1
MATCH: MOV AH,09H
MOV DX,OFFSET TRUE ;如果匹对
INT 21H
JMP DONE
NOMATCH: MOV AH,09H ;如果不匹对
MOV DX,OFFSET FALSE
INT 21H
JMP DONE
DONE: MOV AH,4CH ;返回操作系统
INT 21H
CODE ENDS
END START
该程序,用了字符串判断操作 REPZ CMPSB 该指令比较的是ds:si和es:di所指向的两个字节如果相等,那么继续进行,不相等,推出,标志位1。然后通过判断标志位,判断该字符串是否相等
小总结
- LEA 是机器指令,OFFSET 是伪指令。
- LEA BX, BUFFER ;在 实际执行 时才会将变量buffer的地址放入bx
- MOV BX, OFFSET BUFFER ;在编译时就已经计算出buffer的地址为4300(假设),然后将上句替换为: mov bx,4300
- lea可以进行比较复杂的计算,比如lea eax,[esi+ebx4],把ebx的值4,加上esi的值,存入eax中。 mov就不可以计算比较复杂的地址,并将地址放入寄存器中。
- OFFSET只能取得用"数据定义伪指令"定义的变量的有效地址,不能取得一般操作数的有效地址
- CMPSB 是字节串比较
- CMPSW 字串比较
- 将源变址寄存器指向数据段中的一 字节( 或字,或双字)减去目的变址寄存器指向附加段中的一字节( 或 字,或 双 字),不保留相减结果, 但设置标志位:OF、SF、ZF、AF、PF 和 CF。每比较 一次, 根据方向标志 DF 及数据类型对源变址寄存器和目的变址寄存器进行修改。【徐洁. 计算机组成原理与汇编语言程序设计(第4版)】
操作 | 过程 | 操作方向 |
---|---|---|
字节操作( CMPSB ) | SI/ ESI ⇐( SI/ ESI) ± 1; DI/ EDI ⇐( DI/ EDI) ± 1 | ( DS:( SI/ ESI )) − ( ES: ( DI/ EDI )) |
字操作 ( CMPSW ) | SI/ ESI ⇐( SI/ ESI) ± 2; DI/ EDI ⇐( DI/ EDI) ± 2 | 同上 |