吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 3298|回复: 69

[汇编] 8086汇编-逻辑运算和位移指令

  [复制链接]
啥都不会 发表于 2022-5-30 10:20 | 显示全部楼层 |阅读模式

前言:
这篇笔记主要逻辑指令、位移指令和循环指令相关知识。

编程语言:
汇编语言

以下为主题内容:

逻辑指令
逻辑指令中,除 NOT 指令不影响标志位,其他逻辑指令都会影响标志位。指令执行之后会使 CF 和 OF 清 0,PF、ZF、SF反映运算结果。

NOT(取反)
指令格式:
[Asm] 纯文本查看 复制代码
NOT OPRD

这条指令把 OPRD 取反,然后再送回 OPRD

范例:
[Asm] 纯文本查看 复制代码
NOT AX
NOT VAR


AND(与)
指令格式:
[Asm] 纯文本查看 复制代码
AND OPRD1,OPRD2

使用逻辑 “与” 运算,将结果传送到目的操作数 OPRD1

范例:
[Asm] 纯文本查看 复制代码
AND DH,DH
AND AX,ES:[SI]


常见用途:
1. 保证操作数不变的情况下,让 CF 位清 0

169685563-4478cdb3-1878-48c3-a779-d3faae19651b.png

2. 将一个字节数据的高 4 位置 0

169685652-fee0fc0d-bdf3-4e8c-bd53-4352242a268f.png

OR(或)
指令格式:
[Asm] 纯文本查看 复制代码
OR OPRD1,OPRD2


使用逻辑 “或” 运算,结果送到目的操作数 OPRD1

范例:
[Asm] 纯文本查看 复制代码
OR AX,8080H
OR CL,AL
OR [BX-3],AX


[Asm] 纯文本查看 复制代码
MOV AL,41H
OR AL,20H


169686370-83679d5a-653e-4c8d-a90d-618bff2c200a.png

XOR(异或)
指令格式:
[Asm] 纯文本查看 复制代码
XOR OPRD1,OPRD2


常见用途:
  • 操作数和 CF 位同时置 0
169687854-94328c1b-3d18-48b9-9216-a1aefea5eb90.png

  • 将一个字节数据的低 4 位取反
169688298-2dbc3d27-e268-4aca-b0fa-58cba50b92be.png

TEST(测试指令)
指令格式:
[Asm] 纯文本查看 复制代码
TEST OPRD1,OPRD2
使用逻辑 “与” 运算,只影响标志位,不会改变 OPRD1。

常见用途:
  • 判断某个位是否为1

169689897-c4776e22-8b0a-4cb3-ae68-2d99041880b3.png

  • 判断这个值是否为0

169689997-1d03662d-e622-4886-84a4-a3a4cc7ed7ad.png

test 指令没有改变操作数,不完全属于逻辑运算指令。


位移指令
所有位移指令如果位移多位,需要将移位位数存放在 CL 寄存器中。

SAL/SHL(算数左移指令/逻辑左移指令)

算数左移和逻辑左移的硬编码相同,没有区别。根据编译器的不同,它只会选择一种汇编指令编译。

指令格式:
[Asm] 纯文本查看 复制代码
SAL OPRD,m
SHL OPRD,m


169691173-98578274-b491-486a-a9ae-16e43c4c998e.png

  • 判断某个位是否为1

169691284-d3fd52ea-6e21-437b-8b7f-f3f2ec681296.png

  • 乘法运算:计算4*2

169691747-f4dde9e8-eaf8-4364-90d7-22ffacdbd6a5.png

SAR(算数右移指令)
指令格式:
[Asm] 纯文本查看 复制代码
SAR OPRD,m

操作数右移m位,同时每一栋一位,左边符号位保持不变,移出的最低位进入标志位CF。

范例:
[Asm] 纯文本查看 复制代码
SAR AL,1
SAR BX,CL


对于有符号数而言,算数右移一位相当于除以2
169696921-7a4fce65-a234-40fc-97a6-951a32be2f8e.png

不建议用在无符号数,容易出错。



SHR(逻辑右移指令)

指令格式:
[Asm] 纯文本查看 复制代码
SHR OPRD,m


范例:
[Asm] 纯文本查看 复制代码
SHR BL,1
SHR AX,CL


对于无符号数而言,逻辑右移相当于除以2
169697606-57ccb595-eba0-4afc-a105-9316b0eb0f49.png

循环位移指令
8086 有四条循环位移指令:ROL(左循环位移),ROR(右循环位移),RCL(带进位左循环位移),RCR(带进位右循环位移)。

169700443-167effac-8fa4-4b74-8287-57cca8624631.png

ROL(左循环位移指令)
每移位一次,操作数左移,其最高位移入最低位,同时最高位也移入进位标志 CF

169700610-22fc07d3-a94b-4caa-8af5-0750b4ecba9a.png

ROR(右循环位移指令)
每移位一次,操作数右移,其最低位移入最高位,同时最低位也移入进位标志 CF

169700713-ec5ce22f-5efe-4631-8058-12c96d9265e0.png

RCL(带进位左循环位移指令)
每移位一次,操作数左移,其最高位移入进位标志 CF,CF 移入最低位。

169700857-e270d623-1eb4-4a23-a0df-6fac4d3873df.png

RCR(带进位右循环位移指令)
每移位一次,操作数右移,其最低位移入进位标志 CF,CF 移入最高位。

169700955-46505c83-742b-47e1-8717-2ee5230f0e20.png

转移指令

无条件转移指令
指令格式:
[Asm] 纯文本查看 复制代码
jmp 标号


条件转移指令分为段内转移和段间转移。

[Asm] 纯文本查看 复制代码
;程序名:jmp1.asm
;测试转移指令
;=============================

assume cs:code

code segment
start:

N:
    mov ax,0
    mov bx,0
    jmp S
P:
    add ax,1
S:
    jmp O
    inc ax
    inc ax
O:
    mov ax,4c00h
    int 21h
code ends
end start


段内转移
段内转移的范围是 -128~127,默认使用一个字表示地址差。

使用 "标号" 进行跳转
"jmp+标号" 硬编码是 "EB+地址",默认地址是一个字大小,不足一个字会使用 90 填充。

169984688-4fe30eb1-f366-4be0-8954-176bd9476983.png

169988466-41f84fdf-958d-4239-9502-bc010970a4ec.png

如果确认一个字节可以表示地址差,那么可以在标号前使用 short 表示。

[Asm] 纯文本查看 复制代码
;程序名:jmp2.asm
;测试转移指令
;=============================

assume cs:code

code segment
start:

N:
    mov ax,0
    mov bx,0
    jmp short S
P:
    add ax,1
S:
    jmp short O
    inc ax
    inc ax
O:
    mov ax,4c00h
    int 21h
code ends
end start



169989572-77907abb-bd6f-4ae8-bc97-cbf39af994b2.png

由此可见,在当时硬盘和内存还很小的情况下,编写程序使用 short 可以节省一些硬盘和内存空间。

使用 "存储单元" 进行跳转
[Asm] 纯文本查看 复制代码
;程序名:jmp3.asm
;转移指令
;=============================

assume cs:code,ds:data

data segment
    addr dw 0eh
data ends

code segment
start:
    mov ax,data
    mov ds,ax
N:
    mov ax,0
    mov bx,0
    jmp addr
P:
    add ax,1
S:
    jmp O
    inc ax
    inc ax
O:
    mov ax,4c00h
    int 21h
code ends
end start



169997205-87d45593-93d3-42d2-97b8-cea673958734.png

使用存储单元跳转是直接,将内存数据传输到 IP 寄存器中。如果要这样写,需要手动计算 IP 的值,很容易出错。



使用 "$+立即数" 进行跳转
"\$" 伪指令表示 IP 寄存器的值。使用 "jmp \$+立即数" 可以跳转到相应地址。

[Asm] 纯文本查看 复制代码
;程序名:jmp$.asm
;转移指令
;=============================

assume cs:code,ds:data

data segment
    addr dw 0eh
data ends

code segment
start:
    mov ax,data
    mov ds,ax
N:
    mov ax,0
    mov bx,0
    jmp $+5
P:
    add ax,1
S:
    jmp O
    inc ax
    inc ax
O:
    mov ax,4c00h
    int 21h
code ends
end start


170003764-294870a1-d28e-4f04-9451-5d75cfde10e4.png

段间直接转移
170848883-15968a75-ef03-49ce-9d14-e24c2fcca3ba.png

170848899-064afafa-d5f2-4a2b-8ca7-8e15fe26df78.png

段间间接转移
170848909-6ad39471-35e8-47cb-956f-713d3c314012.png

条件转移指令
170849231-c6c750fd-0cd9-4dd5-b1b3-b8388073a588.png

170849836-980b3a18-4acf-4ddc-bd9d-3fe372897e5c.png

### 循环指令
条件转移指令和无条件转移指令可以实现循环,但为了方便循环指令的实现,8086 还提供了四条循环指令。
循环指令不影响各标志位

LOOP(计数循环指令)
170850629-2472c4c8-0087-4a19-87cc-d9ccf708bae2.png

LOOPE/LOOPZ(等于/全零循环指令)
170850671-5ebd20fb-c3f0-4072-bb72-ac352ac273fa.png

LOOPNE/LOOPNZ(不等于/非零循环指令)
170850699-869d664c-c460-4732-8150-d25bf3c5b18a.png

JCXZ(跳转指令)
170850766-a81f1d94-23b1-4247-8db7-5c83bb357089.png


代码补充

[Asm] 纯文本查看 复制代码
;程序名:shr.asm
;功能:假设 DATA1 和 DATA2各长4位,分别存放在 AL 寄存器的低 4 位和高 4 位中,
;现在要把它们分别存放在BL寄存器和BH寄存器的低 4 位
;==========================================================================
assume cs:code,ds:data

data segment
    DATA1 db 08h
    DATA2 db 04h
data ends
code segment
start:
    mov ax,data
    mov ds,ax
    ;
    mov ax,0
    mov cl,4
    ;
    mov al,DATA1
    shl al,cl
    or al,DATA2
    mov bl,al
    shl bx,cl
    shr bl,cl
    ;
    mov ax,4c00h
    int 21h
code ends
end start




[Asm] 纯文本查看 复制代码
;程序名:ROL.asm
;功能:实现把AL的高4位与低4位交换。
;================================

assume cs:code

code segment
start:
    xor ax,ax
    mov al,37h
    mov cl,4
    rol al,cl
    ;
    mov ax,4c00h
    int 21h
code ends
end start




[Asm] 纯文本查看 复制代码
;程序名:ROR.asm
;功能:实现把AL的最低位送入BL的最低位,仍保持AL不变
;=================================================

assume cs:code

code segment
start:
    xor ax,ax
    xor bx,bx
    mov al,29h
    mov bl,28h
    ;
loop1:
    ror bl,1
    ror al,1
    rcl bl,1
    rol al,1
    ;
    mov ax,4c00h
    int 21h
code ends
end start



[Asm] 纯文本查看 复制代码
;程序名:shift.asm
;功能:设DATA1存放在AL的低4位,DATA2存放在AH的低4位,DATA3存放在SI的低4位,DATA4存放在SI的高4位。
;      现在要把这四个数据合并为16位,并存放到DX寄存器中。

assume cs:code,ds:data

data segment
      DATA1 db 1
      DATA2 db 2
      DATA3 db 3
      DATA4 db 4
data ends

code segment
start:
      mov ax,data
      mov ds,ax
      ;
      mov cl,4
      mov al,DATA1
      mov ah,DATA2
      mov bl,DATA3
      mov bh,DATA4
      shl bh,cl
      mov si,bx
      xor bx,bx
      ;
      rol ax,cl
      shr ah,cl
      or ah,al
      ;
      mov dx,si
      shl dl,cl
      shr dh,cl
      or dl,dh
      mov dh,ah
      ;
      mov ax,4c00h
      int 21h
code ends
end start



[Asm] 纯文本查看 复制代码
;程序名:jae.asm
;功能:比较两个无符号数的大小,较大的数存放在 AX 中,较小的数存放在 BX 中
assume cs:code,ds:data

data segment
num1 dw 24
num2 dw 35
data ends

code segment
start:
    mov ax,data
    mov ds,ax
    ;
    mov ax,num1
    mov bx,num2
    cmp ax,bx
    jae stop
    xchg ax,bx
stop:
    mov ax,4c00h
    int 21h
code ends
end start




[Asm] 纯文本查看 复制代码
;程序名:jge.asm
;功能:比较两个无符号数的大小,较大的数存放在 AX 中,较小的数存放在 BX 中
assume cs:code,ds:data

data segment
num1 dw 24
num2 dw 35
data ends

code segment
start:
    mov ax,data
    mov ds,ax
    ;
    mov ax,num1
    mov bx,num2
    cmp ax,bx
    jge stop
    xchg ax,bx
stop:
    mov ax,4c00h
    int 21h
code ends
end start




[Asm] 纯文本查看 复制代码
;程序名:loop.asm
;功能:十六进制数转换成ASCII输出
;=============================
assume cs:code,ds:data

data segment
val dw 0A2B4h
result db ?,?,?,?,'H',24H
data ends

code segment
start:
    mov ax,data
    mov ds,ax
    xor si,si
    mov cx,4
    mov ax,val[si]
    ;
loop_start:
    push cx
    mov cl,4
    rol ax,cl
    push ax
    and al,0fh
    cmp al,9
    jnb char
    add al,30h
    mov result[si],al
    jmp loop_end
    ;
char:
    add al,37h
    mov result[si],al
    ;
loop_end:
    pop ax
    pop cx
    inc si
    loop loop_start
    ;
    mov dx,offset result
    mov ah,9
    int 21h
    ;
    mov ax,4c00h
    int 21h
code ends
end start




[Asm] 纯文本查看 复制代码
;程序名:loop1.asm
;功能:把从偏移 1000H 开始的 512 个字节的数据复制到从偏移 3000H 开始的缓冲区中
assume cs:code

code segment
start:
    mov si,1000H
    mov di,3000H
    mov cx,512
next:
    mov al,[si]
    inc si
    mov [di],al
    inc di
    loop next
    ;
    mov ax,4c00h
    int 21h
code ends
end start


[Asm] 纯文本查看 复制代码
;程序名:loopz.asm
;功能:查找第一个非 'A' 字符,找到 BX 保存该字符的偏移地址,找不到 BX=0FFFFh
;=========================================================================
assume cs:code,ds:data

data segment
val db 'AAAAAAAA',24h
data ends

code segment
start:
    mov ax,data
    mov ds,ax
    mov cx,8
    xor si,si
    ;
loop_start:
    mov al,val[si]
    inc si
    cmp al,41h
    ;loopz:cx不为0 and zf 标志位为 1 才会继续循环,只要其中一个条件不成立就会跳出循环
    loopz loop_start
    cmp byte ptr [si],24H
    jz no_find
    mov bx,si
    jmp stop
no_find:
    mov bx,-1
stop:
    mov ax,4c00h
    int 21h
code ends
end start




[Asm] 纯文本查看 复制代码
;程序名:loopz2.asm
;功能:查找第一个非 'A' 字符,找到 BX 保存该字符的偏移地址,找不到 BX=0FFFFh
;=========================================================================
assume cs:code,ds:data

data segment
val db 'AAABABAA'
len = $ - val
data ends

code segment
start:
    mov ax,data
    mov ds,ax
    mov cx,len
    xor si,si
    ;
loop_start:
    mov al,val[si]
    inc si
    cmp al,41h
    ;循环判断字符串中的字符 'A'
    loopz loop_start
    ;如果 CX = 0,说明没有找到字符 'A'
    cmp cx,0
    jz no_find
    mov bx,si
    jmp stop
no_find:
    mov bx,-1
stop:
    mov ax,4c00h
    int 21h
code ends
end start



[Asm] 纯文本查看 复制代码
;程序名:loopz3.asm
;功能:查找第一个非 'A' 字符,找到 BX 保存该字符的偏移地址,找不到 BX=0FFFFh
;=========================================================================
assume cs:code,ds:data

data segment
val db 'AAABABAA'
len = $ - val
data ends

code segment
start:
    mov ax,data
    mov ds,ax
    mov cx,len
    xor si,si
loop_start:
    mov al,val[si]
    inc si
    cmp al,41h
    loopz loop_start
    ;正常循环结束后的 CX = 0
    jz no_find
    mov bx,si
    jmp stop
no_find:
    mov bx,-1
stop:
    mov ax,4c00h
    int 21h
code ends
end start



评分

参与人数 11威望 +1 HB +22 THX +3 收起 理由
消逝的过去 + 2
今日下雨 + 1
后学真 + 1 [吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意!
纯英文 + 1
青衣 + 1
风里去 + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
微熊猫 + 2 + 1
zyyujq + 1
zxjzzh + 2 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
taykey + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
Shark恒 + 1 + 10 + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
RmKcTkHa 发表于 2022-5-30 10:36 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
omgTsQ6917 发表于 2022-5-30 10:37 | 显示全部楼层

楼主的帖子不错,多发点~
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
IKfTXCG95807 发表于 2022-5-30 10:39 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
JYmejiO 发表于 2022-5-30 10:44 | 显示全部楼层

谢谢分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
oQP27 发表于 2022-5-30 10:45 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
SzuPpJd5860 发表于 2022-5-30 10:48 | 显示全部楼层

感谢楼主
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
YkwPF 发表于 2022-5-30 10:59 | 显示全部楼层

谢谢分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
uYtUSF 发表于 2022-5-30 11:09 | 显示全部楼层

谢谢分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
veUDqa251 发表于 2022-5-30 11:12 | 显示全部楼层

有楼主这样的热心人真好
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层
9层
10层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表