8086汇编(16位汇编)学习笔记05.asm基础语法和串操作

8086汇编(16位汇编)学习笔记05.asm基础语法和串操作-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net

asm基础语法

1. 环境配置

img

xp环境配置

1.拷贝masm615到指定目录

2.将masm615目录添加进环境变量

3.在cmd中输入ml,可以识别即配置成功

img

dosbox环境配置

1.拷贝masm611到指定目录

2.将masm611所在目录添挂载进dosbox

3.将masm611目录在dosbox中添加进环境变量

4.在cmd中输入ml,可以识别即配置成功

img

window10 环境配置

masm615 是 32位程序的(可以在xp系统上用) 因此要用 masm611

1.把文件复制到 dosbox-x 挂载的文件目录下

img

img

img

这样比较麻烦,所以可以把路径放入环境变量,在放入配置文件 set path=%path%;c:\masm611\

img

img

2. 入口和段
入口
CODE segment                                               

START:                              

	mov ax, ax                              

CODE ends   

//表示标号  START  的第一行代码就是程序起点                                                   

end START  
  1. 一个程序必须至少有一个段
  2. 一个程序中可以定义多个段
  3. 段不能嵌套
  4. 段可以重名,重名的段会被编译到同一块内存中
  5. 一般代码和数据是放在不同段内,一般有个代码段,一个数据段,一个栈段

格式:

段名 segment
ends 段名
TEST0 segment
    mov cx, cx
TEST0 ends

CODE segment
    mov dx, dx
CODE ends

CODE segment
    mov bx, bx 
CODE ends


CODE segment

START:
    mov ax, ax
CODE ends

end START
注释
汇编中使用分号( ; )来标注行注释,只有行注释,没有块注释
;这里是注释

mov ax, bx ;这里是注释
常量
整数

1.整数可以支持多个进制

2.数值必须以数字开头,如果非数字,前面必须加0 (如 abcH 必须写成 0abcH)

3.负数前面可以加减号(-)

img

img

字符
  1. 字符可以用单引号(‘)或双引号(””)

mov byte ptr [bx], '$'

img

5. 变量
整形

1.整数可以支持多个类型

2.整数可以有多个初值,未初始化的值用问号(?)表示

3.变量一般定义在一个单独的段中

变量名    类型    初始值
val        dd      5566h 

img

img

img

img

img

img

img

字符串

1.字符串都可以用单引号(‘)或双引号(””),单引号和双引号作用一样

2.字符串一般以美元符$结尾

g_sz db "hello world$"; 16位汇编中以美元符结尾

img

数组
;这里是数据
data segment    ;变量不允许重名 
   g_ary  dw  12,13,14,15,16,17  ;长度等于你定义的个数
   g_ary1 dw  16 dup(55h)        ;表示定义了一个长度16,初始值都是55的数组 
   g_ary2 dw  66h,4 dup(8888h),9999h,3 dup(7777h)

   g_bt db 12H     ;一个字节
   g_w  dw ?       ;未初始化
   g_w1  dw 1213h   ;双字
   g_w2 dw ?       ;未初始化
   g_dd1 dd 1234h   ;四个字节
   g_sz db "hello world $" ;汇编不会自动帮你加'\0'

data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
  
     mov al,g_bt     ;将变量 g_bt 的值给al
     mov ax,g_w1     ;将变量 g_w1 的值给bx
     mov g_w,1234h   ;给未初数化变量 g_w 赋值
     mov g_w2,bx     ;将bx的值,赋值给 g_w2
   

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点

格式:

名字 类型 值1[,值2][,值2][,值2][,值2]
名字 类型 数量 dup (初值)[,数量 dup (初值)][,值]

示例

g_db   db 78h, 96h, 43h;后面跟初始化的值
g_ary  db 256 dup(0), 128 dup(11h);重复256个0,再跟重复128个1

image.png

dup中如果不想给初值,可以直接写 ?

赋值
 g_ary  dw  12 dup(0)  


;给数组元素赋值
lea bx , g_ary  ;获取 g_ary 的偏移地址,即第一个元素的地址
mov  word ptr [bx + 2 * 2],10h ; word是数组元素类型 2*2 是 元素下标 * 元素大小 
                               ; 计算元素偏移值 , 10H 是要赋值的值
                                  
取值
g_ary  dw  12 dup(0)  


;取出数组指定元素的值
lea bx , g_ary  ;获取 g_ary 的偏移地址,即第一个元素的地址
mov  ax,word ptr [bx + 2 * 2] ; word是数组元素类型 2 * 2 是 元素下标 * 元素大小 
                              ; 计算元素偏移值 
属性

masm提供了很多伪指令,可以获取变量的大小和地址,称之为变量的属性。

img

;这里是数据
data segment    ;变量不允许重名 
   g_ary  dw  12 dup(0) 
   ; 如果 g_ary  dw  888h,12 dup(0)  那么属性就是以g_ary dw 888h来算
   g_bt   db  11h
 
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
  
    mov ax, set    g_bt   ;把变量g_bt的段基址给 ax
    mov ax, size   g_bt   ;将变量g_bt的大小给 ax
    mov ax, type   g_bt   ;将变量g_bt的元素类型大小给 ax
    mov ax, length g_bt   ;将变量g_bt的元素个数给 ax

    mov ax, size   g_ary  ;将变量g_ary的大小给 ax
    mov ax, type   g_ary  ;将变量g_ary的元素类型大小给 ax
    mov ax, length g_ary  ;将变量g_ary的元素个数给 ax
  
     ;给数组元素赋值
     lea bx , g_ary  ;获取 g_ary 的偏移地址,即第一个元素的地址
     mov  word ptr [bx + 2 * 2],10h ; word是数组元素类型 2*2 是 元素下标 * 元素大小 
                                    ; 计算元素偏移值 , 10H 是要赋值的值

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点

img

堆栈

stack关键字让程序在被加载的时候指定ss、bp和sp 。

使用数组为栈设置大小

;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 
   g_ary  dw  12 dup(0)
   g_bt   db  11h
 

data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
  
    mov ax, seg    g_bt   ;把变量g_bt的段基址给 ax
    mov ax, size   g_bt   ;将变量g_bt的大小给 ax
    mov ax, type   g_bt   ;将变量g_bt的元素类型大小给 ax
    mov ax, length g_bt   ;将变量g_bt的元素个数给 ax

    mov ax, size   g_ary  ;将变量g_ary的大小给 ax
    mov ax, type   g_ary  ;将变量g_ary的元素类型大小给 ax
    mov ax, length g_ary  ;将变量g_ary的元素个数给 ax

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点

img

6. 调用dos功能号
功能号

1.dos系统提供的功能(API),通过21号中断来调用

2.每个功能都有一个编号,通过AH指定功能号

3.每个功能的参数查看手册

📎指令字典2005II.zip

img

img

img

用的最多的是21号 中断

程序结束

img

使用方法: 将功能编号 给 al 在 调用 int 21

;mov ah,4CH    ;程序结束
    ;mov al,00     ;返回值 类似于 return 0 
  
    mov ax,4C00H  ; 上面2条指令合成一条  
    int 21h   ;使用21号中断

image.png

6输出一个字符串

DS:减一串地址

显示字符串

60

$'结束字符串

image.png

;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 
    g_sz db "hello world",0dh,0ah,"$"   ;用于输出的字符串 0dh \r  0ah \n
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
   
   lea dx,g_sz           ;获取字符串 g_sz 的首地址
   ;mov dx, offset  g_sz  ;获取字符串 g_sz 的段偏移值,即首地址跟上面效果一样

   mov ah,9   ; 将功能编号给ah
   int 21H     ;调用21号中断

    ;mov ah,4CH    ;程序结束
    ;mov al,00     ;返回值 类似于 return 0 
  
    mov ax,4C00H  ; 上面2条指令合成一条  
    int 21h   ;使用21号中断

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点

img

输入字符串

img

;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 
  g_sz db 32 dup(0)   ;用于输入的字符串
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
   
   lea dx,g_sz           ;获取字符串 g_sz 的首地址
   ;mov dx, offset  g_sz  ;获取字符串 g_sz 的段偏移值,即首地址跟上面效果一样
  
   mov byte ptr [bx],size  g_sz  ;把字符串大小给  byte ptr [bx]
   mov dx,bx                     ;把地址给 dx 

   mov ah,0aH   ; 将功能编号给ah
   int 21H     ;调用21号中断

    ;mov ah,4CH    ;程序结束
    ;mov al,00     ;返回值 类似于 return 0 
  
    mov ax,4C00H  ; 上面2条指令合成一条  
    int 21h   ;使用21号中断

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点

img

中断

1.中断是由cpu提供的流程跳转指令,类似函数调用

2.在00:00位置存储着一个双字数组,大小为256,称作中断向量表

3.数组元素为逻辑地址**段基址****:**段偏移

4.int n的意思是从第n个元素获取地址,然后跳转执行

img

img

img

总结

每一个文件 以 end 作结尾,每个文件至少有一个段,程序的入口点用标号 ,标号名放在end后面.多个文件只能有一个标号放在end后面,一个段里面可以定义变量,可以写代码,但是一般我们会把,代码,数据,栈分开,放在不同段里面

示例:

img

code  segment   ;段开始

START:  ;标号
  mov  ax,ax 
  mov  ax,ax 
  mov  ax,ax 

code ends        ;段结束

end  START  ;代表从标号  START 的第一行代码作为运行起点

img

 注意文件要放在挂在的文件中

编译

img

img

img

img

链接

img

img

调试

img

编译链接脚本
● 编译+调试 脚本
  ml/c %1.asm
  link %1.obj
  debug %1.exe
  
文件后缀要改成 .bat ,而且要跟文件同目录

image.png

image.png

串操作

• 串传送MOVS(move string)

• 串存储STOS(store string)

• 串读取LODS(load string)

• 串比较CMPS

• 串扫描SCAS(scan string)

串传送MOVS(move string)

把字节或字操作数从主存的源地址传送至目的地址

(1)MOVSB

作用:字节 串传送:ES:[DI]←DS:[SI] ( SI←SI±1,DI←DI±1 )
从 DS:[SI] 取一个字节 存到  ES:[DI]

(2)MOVSW

作用:字  串传送:ES:[DI]←DS:[SI](SI←SI±2,DI←DI±2)
从 DS:[SI] 取一个字 存到  ES:[DI]

(3)MOVSD

作用:双字串 传送:ES:[EDI]←DS:[ESI](SI←SI±4,DI←DI±4)
从 DS:[SI] 取一个双字 存到  ES:[DI]

举例:

memcpy
;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 

  g_sz db "hello world",0dh,0ah,"$"   
  g_sz1 db 32 dup(0)   ;用于输入的字符串
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
   assume ds:data   ;指定data段 作为 ds 段
   mov ax,data      ;先把data的偏移值给ax
   mov ds,ax        ;ax再把data的偏移值给ds
                    ;不直接给是因为没有立即数到段寄存器
                  
   lea si,g_sz       ;获取字符串 g_sz 的首地址
   lea di,g_sz1      ;获取字符串 g_sz1 的首地址
 
   mov ax,ds        ;因为是从 ES:[DI]←DS:[SI],所以把 es  设成ds 
   mov es,ax
   movsb            ;从DS:[SI]拷贝一个字节数据到ES:[DI]
   movsb            ;从DS:[SI]拷贝一个字节数据到ES:[DI]
   movsb            ;从DS:[SI]拷贝一个字节数据到ES:[DI]
   movsb
   movsb
   movsb

   ;mov ah,4CH    ;程序结束
   ;mov al,00     ;返回值 类似于 return 0 
  
   mov ax,4C00H  ; 上面2条指令合成一条  
   int 21h   ;使用21号中断

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点

image.png

串存储STOS(store string)

把AL或AX数据传送至目的地址

(1)STOSB

作用:字节串存储 ES:[DI]←AL    DI←DI±1
把Al中的值给   ES:[DI]

(2)STOSW

作用:字串存储:ES:[DI]←AX DI←DI±2

把AX 中的值给   ES:[DI]

(3) STOSD

作用:双字串存储:ES:[EDI]←EAX   DI←DI±4
把 EAX   中的值给  ES:[EDI]

举例:

memset
;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 

  g_sz db "hello world",0dh,0ah,"$"   
  g_sz1 db 32 dup(0)   ;用于输入的字符串
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
   assume ds:data   ;指定data段 作为 ds 段
   mov ax,data      ;先把data的偏移值给ax
   mov ds,ax        ;ax再把data的偏移值给ds
                    ;不直接给是因为没有立即数到段寄存器

   mov ax,ds       
   mov es,ax

   mov al,66h
   lea di,g_sz1      ;获取字符串 g_sz 的首地址
   stosb             ;将 al (66H),依次赋值给 g_sz1 开始的 各个字节 
   stosb 
   stosb
   stosb

   ;mov ah,4CH    ;程序结束
   ;mov al,00     ;返回值 类似于 return 0 
  
   mov ax,4C00H  ; 上面2条指令合成一条  
   int 21h   ;使用21号中断

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点

img

串读取LODS(load string)
把指定主存单元的数据传送给AL或AX
(1)LODSB
作用:字节串读取 AL←DS:[SI](SI←SI±1)
从  DS:[SI]  读取一个字节 给 al
(2)LODSW
作用:字串读取 AX←DS:[SI] (SI←SI±2)
(3)LODSD
作用:双字串读取 EAX← DS:[ESI] (SI←SI±4)
;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 

  g_sz db "hello world",0dh,0ah,"$"   
  g_sz1 db 32 dup(0)   ;用于输入的字符串
  g_sz2 db "hi$" 
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
   assume ds:data   ;指定data段 作为 ds 段
   mov ax,data      ;先把data的偏移值给ax
   mov ds,ax        ;ax再把data的偏移值给ds
                    ;不直接给是因为没有立即数到段寄存器

   mov ax,ds       
   mov es,ax

   mov al,0
   lea si,g_sz      ;获取字符串 g_sz 的首地址
   lodsb
   lodsb
   lodsb

   mov ax,4C00H  ; 上面2条指令合成一条  
   int 21h   ;使用21号中断

code ends        ;段结束
end  START  ;代表从该标号第一行代码作为运行起点

img

串比较CMPS

将主存中的源操作数减去至目的操作数,以便设置标志,进而比较两操作数之间的关系

(1)CMPSB

作用:字节串比较:DS:[SI]-ES:[DI]( SI←SI±1,DI←DI±1 )

(2)CMPSW

作用:字串比较:DS:[SI]-ES:[DI](SI←SI±2,DI←DI±2)

(3)CMPSD

作用:双字串比较:DS:[ESI]-ES:[EDI] ( SI←SI±4,DI←DI±4 )

举例:

strstr

;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 

  g_sz db "hello world",0dh,0ah,"$"   
  g_sz1 db 32 dup(0)   ;用于输入的字符串
  g_sz2 db "hi$" 
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
   assume ds:data   ;指定data段 作为 ds 段
   mov ax,data      ;先把data的偏移值给ax
   mov ds,ax        ;ax再把data的偏移值给ds
                    ;不直接给是因为没有立即数到段寄存器

   mov ax,ds       
   mov es,ax

   lea si,g_sz      ;获取字符串 g_sz 的首地址
   lea di,g_sz2      ;获取字符串 g_sz2 的首地址
   cmpsb
   cmpsb

 
   mov ax,4C00H  ; 上面2条指令合成一条  
   int 21h   ;使用21号中断

code ends        ;段结束

end  START  ;代表从该标号第一行代码作为运行起点
串扫描SCAS(scan string)

•作用:将AL/AX减去至目的操作数,以便设置标志,进而比较AL/AX与操作数之间的关系

一般用来找某个字符,确定字符串长度 ,例如 16asm 字符串以 "

结束那我们从字符串开始到找到"结束,那我们从字符串开始,到找到′'

Di 的 值 ,就是字符串长度, 或者判断字符串中是否有某个字符,或者字符串中某个字符的下标

(1)SCASB

作用:字节串扫描:AL-ES:[DI](DI←DI±1)

(2)SCASW

作用:字串扫描:AX-ES:[DI](DI←DI±2)

(3) SCASD

作用:字串扫描:EAX-ES:[EDI](DI←DI±4)

举例:strlen

;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 

  g_sz db "hello world",0dh,0ah,"$"   
  g_sz1 db 32 dup(0)   ;用于输入的字符串
  g_sz2 db "hi$" 
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
   assume ds:data   ;指定data段 作为 ds 段
   mov ax,data      ;先把data的偏移值给ax
   mov ds,ax        ;ax再把data的偏移值给ds
                    ;不直接给是因为没有立即数到段寄存器

   mov ax,ds       
   mov es,ax

   mov al,'l'
   lea di,g_sz      ;获取字符串 g_sz 的首地址
  
   scasb
   scasb
   scasb
   scasb

  
   mov ax,4C00H  ; 上面2条指令合成一条  
   int 21h   ;使用21号中断

code ends        ;段结束
end  START  ;代表从该标号第一行代码作为运行起点

img

重复前缀指令

只能用于串操作指令

串操作指令执行一次,仅对数据串中的一个字节或字进行操作。

串操作指令前,都可以加一个重复前缀,实现串操作的重复执行。重复次数隐含在CX寄存器中。

重复前缀分2类,3条指令:

配合不影响标志的 MOVS、STOS(和LODS)指令的 REP 前缀

配合影响标志的 CMPS 和 SCAS 指令的 REPZ 和 REPNZ 前缀

无条件重复前缀指令REP

每执行一次串指令,CX减1,直到CX=0,重复执行结束。

理解为:当数据串没有结束(CX≠0),则继续传送。

举例:

REP LODS/LODSB/LODSW/LODSD

REP STOS/STOSB/STOSW/STOSD

REP MOVS/MOVSB/MOVSW/MOVSD

;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 

  g_sz db "hello world",0dh,0ah,"$"   
  g_sz1 db 32 dup(0)   ;用于输入的字符串
  g_sz2 db "hi$" 
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
   assume ds:data   ;指定data段 作为 ds 段
   mov ax,data      ;先把data的偏移值给ax
   mov ds,ax        ;ax再把data的偏移值给ds
                    ;不直接给是因为没有立即数到段寄存器

   mov ax,ds       
   mov es,ax


   lea si,g_sz      ;获取字符串 g_sz 的首地址
   lea di,g_sz1     ;获取字符串 g_sz1 的首地址
   mov cx, offset g_sz1 - offset g_sz  ;计算字符串 g_sz 长度
   
   rep movsb    ;将 字符串g_sz的内容 全部拷贝到  g_sz1 , cx等于 g_sz 长度



   mov ax,4C00H  ; 上面2条指令合成一条  
   int 21h   ;使用21号中断

code ends        ;段结束
end  START  ;代表从该标号第一行代码作为运行起点

img

条件重复前缀指令REPZ
每执行一次串指令,CX减1。
 

并判断ZF是否为0。

只要CX=0或ZF=0,重复执行结束。

•理解:当数据串没有结束(CX≠0),并且串相等(ZF=1),则继续比较。

•举例:

REPE/REPZ      SCAS/SCASB/SCASW/SCASD
REPE/REPZ      CMPS/CMPSB/CMPSW/CMPSD

作用: 比较2个字符串是否一样 ,如果CF 等于0 就代表一样

;栈段
stack segment  stack   ; segment 后面跟关键字  stack ,说明这是一个栈段
   db  256 dup(1)
stack ends

;这里是数据
data segment    ;变量不允许重名 

  g_sz db "hello world",0dh,0ah,"$"   
  g_sz1 db 32 dup(0)   ;用于输入的字符串
  g_sz2 db "hello$" 
  g_sz3 db "hello world",0dh,0ah,"$" 
data ends

;这里是代码
code  segment   ;段开始
 
START:  ;标号
   assume ds:data   ;指定data段 作为 ds 段
   mov ax,data      ;先把data的偏移值给ax
   mov ds,ax        ;ax再把data的偏移值给ds
                    ;不直接给是因为没有立即数到段寄存器

   mov ax,ds       
   mov es,ax


   lea si,g_sz      ;获取字符串 g_sz 的首地址
   lea di,g_sz2     ;获取字符串 g_sz2 的首地址
   mov cx, offset g_sz1 - offset g_sz  ;计算字符串 g_sz 长度
   
   repz cmpsb    ;ZF位是0 或者 CX = 0 结束 

   lea si,g_sz      ;获取字符串 g_sz 的首地址
   lea di,g_sz3     ;获取字符串 g_sz2 的首地址
   mov cx, offset g_sz1 - offset g_sz  ;计算字符串 g_sz 长度
   repz cmpsb    ;ZF位是0 或者 CX = 0 结束 



   mov ax,4C00H  ; 上面2条指令合成一条  
   int 21h   ;使用21号中断

code ends        ;段结束
end  START  ;代表从该标号第一行代码作为运行起点

img

条件重复前缀指令REPNZ

每执行一次串指令,CX减1。

 

并判断ZF是否为1

只要CX=0 或  ZF=1,重复执行结束。

•理解:当数据串没有结束(CX≠0),并且串不相等(ZF=0),则继续比较。

•举例:

REPNE/REPNZ  SCAS/SCASB/SCASW/SCASD
REPNE/REPNZ   CMPS/CMPSB/CMPSW/CMPSD

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/943001.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C/C++ 数据结构与算法【树和二叉树】 树和二叉树,二叉树先中后序遍历详细解析【日常学习,考研必备】带图+详细代码

一、树介绍 1)树的定义 树 (Tree) 是n(n≥0) 个结点的有限集。 若n 0,称为空树; 若n > 0,则它满足如下两个条件: (1)有且仅有一个特定的称为(Root)的结点; (2)其余结点可分为m(m≥0)个…

MVC架构模式

分析AccountTransferServlet类都负责了什么? 数据接收核心的业务处理数据库表中数据的crud操作负责了页面的数据展示做了很多 在不使用MVC架构模式的前提下,完成银行账户转账的缺点: 代码的复用性太差。因为没有进行职能分工,没有…

打破视障壁垒,百度文心快码无障碍版本助力视障IT从业者就业无“碍”

有AI无碍 钟科:被黑暗卡住的开发梦 提起视障群体的就业,绝大部分人可能只能想到盲人按摩。但你知道吗?视障人士也能写代码。 钟科,一个曾经“被黑暗困住”的人,他的世界,因为一场突如其来的疾病&#xff0c…

【RAG实战】语言模型基础

语言模型赋予了计算机理解和生成人类语言的能力。它结合了统计学原理和深度神经网络技术,通过对大量的样本数据进行复杂的概率分布分析来学习语言结构的内在模式和相关性。具体地,语言模型可根据上下文中已出现的词序列,使用概率推断来预测接…

48页PPT|2024智慧仓储解决方案解读

本文概述了智慧物流仓储建设方案的行业洞察、业务蓝图及建设方案。首先,从政策层面分析了2012年至2020年间国家发布的促进仓储业、物流业转型升级的政策,这些政策强调了自动化、标准化、信息化水平的提升,以及智能化立体仓库的建设&#xff0…

Matlab环形柱状图

数据准备: 名称 数值 Aa 21 Bb 23 Cc 35 Dd 47 保存为Excel文件后: % Load data from Excel file filename data.xlsx; % Ensure the file is in the current folder or provide full path dataTable readtable(filena…

flask后端开发(3):html模板渲染

目录 渲染模板html模板获取路由参数 gitcode地址: https://gitcode.com/qq_43920838/flask_project.git 渲染模板 这样就能够通过html文件来渲染前端,而不是通过return了 html模板获取路由参数

15 break和continue

while True: content input("请输入你要喷的内容") print("发送给下路",content) #上述的程序如果没有外力干扰:程序会一直进行输入下去 #break:就能让当前这个循环立即进行停止 while True: content input("请输入…

Python9-作业2

记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化 python基础8-灵活运用顺序、选择、循环结构 作业2九九乘法表三种方式打印九九乘法表使用两个嵌套循环使用列表推导式和…

微信小程序 不同角色进入不同页面、呈现不同底部导航栏

遇到这个需求之前一直使用的小程序默认底部导航栏,且小程序默认入口页面为pages/index/index,要使不同角色呈现不同底部导航栏,必须要在不同页面引用不同的自定义导航栏。本篇将结合分包(subPackages)展开以下三步叙述…

表达式语句、复合语句和空语句

欢迎拜访:雾里看山-CSDN博客 本篇主题:表达式语句、复合语句和空语句 发布时间:2024.12.26 隶属专栏:C语言 目录 1. 表达式语句定义作用常见类型赋值语句函数调用语句 2. 复合语句定义作用变量作用域 3. 空语句定义作用 1. 表达式…

Linux arm 编译安装glibc-2.29

重要的话说三遍: !!!!!不要轻易自己去安装glibc!!!!! !!!!!不要轻易自己去安装glibc&a…

20241225在ubuntu22.04.5下使用smartmontools命令查看ssd的寿命

20241225在ubuntu22.04.5下使用smartmontools命令查看ssd的寿命 2024/12/25 15:10 rootrootrootroot-ThinkBook-16-G5-IRH:~$ sudo apt install smartmontools rootrootrootroot-ThinkBook-16-G5-IRH:~$ sudo fdisk -l Disk /dev/nvme0n1: 3.73 TiB, 4096805658624 bytes, 800…

大数据学习之Redis 缓存数据库二,Scala分布式语言一

一.Redis 缓存数据库二 26.Redis数据安全_AOF持久化机制 27.Redis数据安全_企业中该如何选择持久化机制 28.Redis集群_主从复制概念 29.Redis集群_主从复制搭建 30.Redis集群_主从复制原理剖析 31.Redis集群_哨兵监控概述 32.Redis集群_配置哨兵监控 33.Redis集群_哨兵监控原理…

Datawhale AI 冬令营学习笔记-零编程基础制作井字棋小游戏

井字棋小游戏是通过豆包MarsCode实现的,没有改动任何的代码,全部是通过对话让AI进行优化和改进。 开始进入正题:进入豆包MarsCode在线IDE,直接点击上方蓝字,或复制链接打开: 豆包 MarsCode - 编程助手。 IDE界面&…

vscode+编程AI配置、使用说明

文章目录 [toc]1、概述2、github copilot2.1 配置2.2 使用文档2.3 使用说明 3、文心快码(Baidu Comate)3.1 配置3.2 使用文档3.3 使用说明 4、豆包(MarsCode)4.1 配置4.2 使用文档4.3 使用说明 5、通义灵码(TONGYI Lin…

Redis数据结构和内部编码以及单线程架构

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Redis数据结构和内部编码以及单线程架构 收录于专栏[redis] 本专栏旨在分享学习Redis的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 …

虚拟机Hyper-V,安装网络宝塔Docker

我下载的是centos-min大小1G,安装后没网络, 关闭防火墙,网络,修改onBootyes,这里需要看下network-Scripts下有什么文件。 然后就可以访问网络了 虚拟机的设置也是默认就好 网络需要设置允许共享-重要 urlhttps://download.bt.cn/i…

红魔电竞PadPro平板解BL+ROOT权限-KernelSU+LSPosed框架支持

红魔Padpro设备目前官方未开放解锁BL,也阉割了很多解锁BL指令,造成大家都不能自主玩机。此规则从红魔8开始,就一直延续下来,后续的机型大概率也是一样的情况。好在依旧有开发者进行适配研究,目前红魔PadPro平板&#x…

Linux-----进程处理(文件IO资源使用)

下面代码是通过父进程和子进程对同一个文件IO资源进行操作,父进程和子进程都对这个进程进行写入操作,我们都知道这两个进程实际上是并发的,所以需要一个同步机制来去操作同一个资源(后面再深入去说明同步的api,这里使用…