Frequently used functions

16th Jun, 2020

System

标准模板

stack  segment para stack
    stack_area dw 100 dup(?)
    stack_btm equ $-stack_area
stack ends

data segment para
divisor     dw 10000, 1000, 100, 10, 1
len equ 126
buffer db len
       db ?
       db len dup(?)
data ends

code segment para
     assume cs:code, ds:data, ss:stack
main proc far

     mov ax, stack
     mov ss, ax
     mov ax, data
     mov ds, ax
     mov es, ax
     mov sp, stack_btm

     ; do something


exit:
     mov ax, 4c00h
     int 21h
main endp
code ends
     end main

String Operations

读取字符串

; 先在data段中定义
data segment para
...
len equ 126
buffer db len ; 预定义的最大允许长度
       db ?   ; 缓冲区内读取到的的实际长度
       db len dup(?)
...
data ends

...
buffer_read:
     mov dx, offset buffer ; DS:DX 为缓冲区的首地址
     mov ah, 0ah ; 调用0ah是读取到缓冲区,回车为结尾
     int 21h ; 系统调用

     mov cl, buffer+1 ; 读缓冲区内字符串实际长度
     xor ch, ch
     mov si, offset buffer+2
     push bx
     mov bx, offset buffer+2
     add bx, cx
     mov byte ptr [bx], 0 ; asciiz
     inc bx
     mov byte ptr [bx], '$'
     pop bx

end_buffer_read:
     do_something

检测一个字符串中有多少字符

     ...
     push es
     push ds
     pop es
     mov di, offset string
     mov cx, strlen ; 字符长度,buffer+1
     mov al, 't' ; char to find
     cld ; 设置DF=0,字符串低地址向高地址走
     mov bx, 0
continueScan:
     repnz scasb ; 按字节寻找
     ; 如果只是要检测有无,在这里直接 JZ FOUND 即可
     jnz endScan ; ZF=0说明已经到达CX=0且最后一位不等,直接退出
     inc bx ; bx统计出现次数
     cmp cx, 0 ; cx!=0 说明后面还有字符
     jnz continueScan
endScan:
     pop es
     ...

比较两个串的大小

; 都先使用上面的字符串读取,在末尾加上一个 0h,'$',0是可以保证一个字符串结束就能出现结果,否则'$'会被正常算进去

     push es ; 先保存ES
     push ds
     pop es 
     mov si, offset string1
     mov di, offset string2
     mov cx, strlen
     cld
     repz cmpsb ; 没比完且相同就继续比,直到CX=0或者ZF=0
     jz equalCase ; 结束repz且ZF=1说明相等
     ja largerCase ; 大于0说明string1>string2
     ; smallerCase string1<string2

     pop es ; 结束后返还ES

Last updated