首页 > 编程语言 >8086汇编(16位汇编)学习笔记06.串操作、流程转移指令

8086汇编(16位汇编)学习笔记06.串操作、流程转移指令

时间:2024-12-27 21:21:26浏览次数:6  
标签:汇编 8086 06 mov 偏移 跳转 ax data ds

8086汇编(16位汇编)学习笔记06.串操作、流程转移指令-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net

 

串操作

源操作数使用si,默认段为DS,可段超越

目的操作数使用di,默认段为ES,不可段超越

img

串方向

串方向由DF标志位影响,可以由指令修改

img

重复前缀

串操作指令一般都配合重复前缀使用,实现内存的批量操作。

img

流程转移指令

1.无条件跳转

直接转移 jmp

img

短跳 jmp 或者 jmp short

偏移值范围是 - 128(80H) 到 127(7FH) , 偏移值大小是 一个字节

;栈段
stack segment stack

stack ends 

;数据段
data segment 
  g_szBuf db 255 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,ax
    mov ax,ax
    jmp   LEABEL1  ; 跳转到标号 LEABEL1
    mov ax,ax
    mov ax,ax
 

 LEABEL1:  
    mov dx,dx
    mov dx,dx
    jmp   LEABEL2  ; 跳转到标号 LEABEL2
    mov dx,dx
   
LEABEL2:  
    mov cx,cx
    mov cx,cx
   
code ends 
end START 

img

img

ip 里面存的是下一条指令的地址. ip被改了,代表下一条指令 也被修改了

img

jum 既然能跳转,那么指令肯定包含了 要跳转的地址信息 ,那么是如果做到的呢

开始IP跳转IP地址偏移值机器码
0009 000f 6 EB04
0013 0017 4 EB02

从表格中我们不难分析出来 EB 代表 jmp 指令 ,其机器码中并没有直接存储 目标地址的 ip信息 ,也不是直接存储偏移,而是地址偏移值 - 2 , 即 下一条指令 到 目标地址的偏移,那为什么不存储本条指令地址和目的地址的偏移,而要存下一条的呢,因为当一条指令执行完,IP地址就指向了下一条指令的ip地址,如果要储存自己和目标指令的偏移,需要先 - 2 ,把ip地址 改回当前自己的,再去算偏移,所以就直接存储 下条指令的 ip 地址 和目标地址的偏移

上面是考虑的是 从上往下跳,如果从下往上跳呢

stack segment stack    ;栈段

stack ends 

data segment     ;数据段
  g_szBuf db 255 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,ax
    mov ax,ax

    jmp   LEABEL1  ; 跳转到标号 LEABEL1

    mov ax,ax
    mov ax,ax
 

 LEABEL1:   

    mov dx,dx
    mov dx,dx
    jmp   LEABEL1  ; 跳转到标号 LEABEL1
    jmp   LEABEL2  ; 跳转到标号 LEABEL2
    mov dx,dx
   
LEABEL2:  
    mov cx,cx
    mov cx,cx

code ends 
end START 

img

开始IP跳转IP地址偏移值机器码
0013 000f -4 EBFA

FA 是 -6 , -4 = -6 +2 ,因此向上跳 也是 记录的 下条指令 到 目标地址的 偏移

近跳 jmp 或者 jmp near

短跳的偏移值 范围 是 - 128(80H) 到 127(7FH) ,如果超过这个范围,那么短跳将无法实现,此时就需要用到近跳

近跳 偏移值范围是 - 32766((8000H)) 到 32765(7FFFH) , 偏移值大小是 一个字

stack segment stack    ;栈段
stack ends 

data segment   ;数据段
  g_szBuf db 255 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,ax
    mov ax,ax

    jmp   LEABEL1  ; 跳转到标号 LEABEL1,此时跳转范围超过一个字节

    mov ax,ax
    mov ax,ax
    db 255 dup(0)  
 
 LEABEL1:   

    mov dx,dx
    mov dx,dx
    jmp   LEABEL1  ; 跳转到标号 LEABEL1
    jmp   LEABEL2  ; 跳转到标号 LEABEL2
    mov dx,dx
   
LEABEL2:  
    mov cx,cx
    mov cx,cx
   
code ends 
end START 

img

此时 这条指令 占3个字节,偏移值是一个 word ,偏移值 是 0103 (小尾保存的 )

000c (下条指令地址) + 0103 (偏移值) = 010F 及目标地址

远跳 jmp far

上面都是在一个段内跳转,如果在不同段内跳转 ,其偏移值 可以 超过 word 的表达范围,此时就需要用远跳

img

stack segment stack    ;栈段
stack ends 

data segment   ;数据段
  g_szBuf db 255 dup(0)
data ends 

code1 segment  ;代码段
  db 64 dup(0)
LEABEL3: 
    xor ax,ax
    xor ax,ax
    db 521 dup(0)

code1 ends

code segment  ;代码段

START: 

    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
    mov ax,ax
    mov ax,ax

    ;jmp far ptr LEABEL3  ; 跳转到标号 LEABEL3,此时是跨段跳
    jmp code1:LEABEL3    ; jmp 段名:标号名  ,效果跟上面一样  

    jmp  LEABEL1  ; 跳转到标号 LEABEL1,此时跳转范围超过一个字节

    mov ax,ax
    mov ax,ax
    db 255 dup(0)  
 
 LEABEL1:   

    mov dx,dx
    mov dx,dx
    jmp   LEABEL1  ; 跳转到标号 LEABEL1
    jmp   LEABEL2  ; 跳转到标号 LEABEL2
    mov dx,dx
   
LEABEL2:  
    mov cx,cx
    mov cx,cx
   
code ends 
end START 

img

指令偏移计算

指令中的偏移值是下一条指令到目的地址的偏移。

img

指令偏移计算练习

计算下列指令的机器码,短跳 0xEB,近跳 0xE9,远跳跳 0xEA。

0AE7:0102 jmp 0120 -- EB1C

  • 120 - 104 = 1C 所以机器码是 E91B02

0AE7:0102 jmp 0320 -- E91B02

  • 因为偏移值超过一个字 ,偏移值是字,因此这条指令是 3个字节 ,下条指令地址是 105

320 - 105 = 021B 所以机器码是 E91B02

0AE7:0102 jmp 20 -- E91BFF

  • 104 - 20 = E4 取反是 FF1C 用一个字节无法表示,所以偏移值应该是用一个字表示,那么该条指令应该是3个字节,下条指令地址应该是 105, 105 - 20 = E5 取反 FF1B 所以机器码是 E91BFF

0AE7:0402 jmp 0100 -- E9FBFD

  • 该条指令偏移值明显看出是一个字,所以指令长度3 ,下条指令地址是 405, 405 - 100 = 305 取反 FDFB,所以机器码是 E9FBFD

0AE7:0122 jmp 0110 -- EBEC

  • 124 - 110 = 14 取反是 EC 所以机器码是 EBEC

img

img

img

img

img

使用寄存器间接转移
  • 格式 jmp reg
  • reg 为通用寄存器,不涉及段寄存器
  • 功能 ip <- reg
  • 只能用于段内转移

img

使用EA的间接转移

把跳转地址存到内存, 跳转时 从 内存里取 出跳转的目标地址

img

注意:

在运用转移的时候需要遵循C语言的流程标准,因为类似于goto,不能从一个函数跳到另外一个函数,影响堆栈平衡。

stack segment stack    ;栈段
stack ends 

data segment   ;数据段
  g_w dw 0
data ends 

code segment  ;代码段

START: 

    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
  
    mov g_w, offset  LEABEL4 ;将 LEABEL4 的  偏移值给 g_w
    jmp g_w  
   
    mov ax,ax
    xor ax,ax

 LEABEL4:   
  
    ;带返回码的退出
    mov ax,4C00H
    int 21 
   
code ends 
end START 

img

img

stack segment stack    ;栈段
stack ends 

data segment   ;数据段
  g_w dw 0
  g_wEA dw 0
  g_wCS dw 0 
data ends 


code1 segment  ;代码段
  db 64 dup(0)
LEABEL3: 
    xor ax,ax
    xor ax,ax
    db 521 dup(0)

code1 ends

code segment  ;代码段

START: 

    assume ds:data   ;指定data段 作为 ds 段
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
                     ;不直接给是因为没有立即数到段寄存器
  
    mov g_wEA,offset LEABEL3 ;将 LEABEL3 的  偏移值给 g_wEA
    ;mov g_wCS,code          ;将 LEABEL3 的 段基址给 g_wCS
    mov  g_wCS,seg LEABEL3   ;将 LEABEL3 的  段基址给 g_wCS
  
    lea bx,g_wEA             ;将 g_wEA 的  偏移地址给 bx
    jmp dword ptr [bx]       ;取出偏移值为bx (即 g_wEA) 处的值,并跳转到该处 

   
    jmp g_w  
   
    mov ax,ax
    xor ax,ax

 LEABEL4:   
  
    ;带返回码的退出
    mov ax,4C00H
    int 21 
   
code ends 
end START 

img

2.条件跳转

依据标志位判断,条件成立则跳转,条件不成立则不跳。

单条件跳转

深色表示常用,需要掌握 ,其他的表是用的比较少,熟悉即可

img

jz/je

比较2个数,相等输出 eaqul 不等输出 not eaqul

stack segment stack    ;栈段
stack ends 

data segment   ;数据段
  g_w0 dw 1122H
  g_w1 dw 3344H
  g_w2 dw 1122H
  g_szEqu db "eaqul",0dh,0ah,'$'
  g_szNEqu db "not eaqul",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,g_w0   ;将 g_w0 的值 给 ax
    cmp ax,g_w1   ; ax的值 和 g_w1 作比较
  
    jz  LEABEL2   ; 如果比较的值相等则跳转 LEABEL2 标号处

    ;输出字符串  g_szNEqu
    lea dx,g_szNEqu
    mov ah,09H
    int 21H

    mov ax,g_w0   ;将 g_w0 的值 给 ax
    cmp ax,g_w2   ; ax的值 和 g_w2 作比较
  
    jz  LEABEL2   ; 如果比较的值相等则跳转 LEABEL2 标号处

    ;输出字符串  g_szNEqu
    lea dx,g_szNEqu
    mov ah,09H
    int 21H

    jmp EXIT

LEABEL2:
    ;输出字符串  g_szEqu
    lea dx,g_szEqu
    mov ah,09H
    int 21H

 EXIT:  

    ;带返回码的退出
    mov ax,4C00H
    int 21H 
   
code ends 
end START 

img

img

img

jcxz

判断2个字符串是否相等,相等则输出 eaqul 否则输出 eaqul not

stack segment stack    ;栈段
stack ends 

data segment   ;数据段
  g_w0 dw 1122H
  g_w1 dw 3344H
  g_w2 dw 1122H
  g_szEqu db "eaqul",0dh,0ah,'$'
  g_szNEqu db "eaqul not ",0dh,0ah,'$'
data ends 

 

code segment  ;代码段

START: 

    assume ds:data   ;指定data段 作为 ds 段
    cld
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
    mov es,ax        ;不直接给是因为没有立即数到段寄存器
  
   
   mov cx,offset g_szNEqu - offset g_szEqu
   lea si,g_szEqu
   lea di,g_szNEqu
   repz cmpsb       ;2个字符串进行比较,直到cx等于0,或者不等退出
   
   jcxz LEABEL2    ;如果 cx 等于 0 则跳转,否则不跳转

    ;输出字符串  g_szNEqu
    lea dx,g_szNEqu
    mov ah,09H
    int 21H

    jmp EXIT

LEABEL2:
    ;输出字符串  g_szEqu
    lea dx,g_szEqu
    mov ah,09H
    int 21H

 EXIT:  

    ;带返回码的退出
    mov ax,4C00H
    int 21H 
   
code ends 
end START 

image.png

C:>DEBUG JMP.EXE

-G

EAQUI

NOT

NORMALLY (0000)

PROGRAM TERMINATED

image.png

无符号数判断

image.png

image.png

有符号数判断

image.png

3.LOOP

使用频率很高 只能用于短转移

格式: loop 标号

image.png

image.png

字符串小写转大写,并输出

stack segment stack    ;栈段
stack ends 

data segment   ;数据段
  g_w0 dw 1122H
  g_w1 dw 3344H
  g_w2 dw 1122H
  g_sz db "helloworld",0,0dh,0ah,'$'
  g_szEqu db "eaqul",0dh,0ah,'$'
  g_szNEqu db "eaqul not ",0dh,0ah,'$'
data ends 

 

code segment  ;代码段

START: 

    assume ds:data   ;指定data段 作为 ds 段
    cld
    mov ax,data      ;先把data的偏移值给ax
    mov ds,ax        ;ax再把data的偏移值给ds
    mov es,ax        ;不直接给是因为没有立即数到段寄存器
  
   
    ;输出字符串  g_szNEqu
    lea dx,g_sz
    mov ah,09H
    int 21H

    mov cx,offset g_szEqu - offset g_sz -4 ;去掉\0 和\r\n,'$'
    lea bx,g_sz


LEABELLOOP:
    ;小写转大写
    mov si,cx
    sub byte ptr[bx+si-1], 20h
    loop LEABELLOOP  

    ;输出字符串  g_szNEqu
    lea dx,g_sz
    mov ah,09H
    int 21H

 EXIT:  

    ;带返回码的退出
    mov ax,4C00H
    int 21H 
   
code ends 

img

标签:汇编,8086,06,mov,偏移,跳转,ax,data,ds
From: https://www.cnblogs.com/weiyuanzhang/p/18636757

相关文章

  • 六、汇编实战
    打印:helloworld在屏幕上输出字符movdl,'a' ;将要打印的字符放到dl中movah,02h;设置显示字符的功能号int21h;调用DOS中断,打印字符在屏幕上输出字符串movah,09h;设置显示字符串的功能号int21H......
  • 《计算机组成及汇编语言原理》阅读笔记:p116-p120
    《计算机组成及汇编语言原理》学习第7天,p116-p120总结,总计5页。一、技术总结1.CPU优化(1)increaseoverallperformancenumber例如:16位电脑提升到32位电脑。(2)multiprocessingOnewaytomakecomputersmoreusefulistoallowthemtorunmorethanoneprogram......
  • 中考阅读理解深入逻辑分析-006 A Stream's Journey to the Sea 一条小溪通往大海的旅
    文章正文Alittlestreamrandownfromahighmountainfar,farawaythroughmanyvillagesandforests,untilitreachedadesert.Thestreamthenthought,“I’vebeenthroughcountlessdifficulties.Ishouldhavenoproblemcrossingthedesert!”Butasshes......
  • linux编译汇编程序
    汇编语言对于大多数程序员来说都是进而远之的,原因当然是汇编语言晦涩难懂,各种指令搞得人头疼,不过汇编语言适当了解一些还是蛮有意思的,今天带大家在Linux上运行第一个汇编程序!在Linux操作系统中,你有很多办法可以实现在屏幕上显示一个字符串,但最简洁的方式是使用Linux内核提供......
  • AWC2406分类库配置
    1)新版本的分类库视图:节点视图:前端用户可见的视图;类视图:实际存储分类对象的视图,同原来胖客户端的分类管理的视图;2)在Linux环境启动cmd命令窗口:TC_ROOT=/usr/Siemens/Teamcenterversion; export TC_ROOTTC_DATA=/usr/Siemens/Teamcenterversion/teamcenterdata; export TC_D......
  • 506 最长上升子序列II
    //506最长上升子序列II.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///*http://oj.daimayuan.top/course/22/problem/647给定一个长度为n的数组a1,a2,…,an,问其中的最长上升子序列的长度。也就是说,我们要找到最大的m以及数组p1,p2,…,pm,满足1≤p1......
  • 8086汇编(16位汇编)学习笔记04.乘除和移位指令
    8086汇编(16位汇编)学习笔记04.乘除和移位指令-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区-BpSend.net乘法和除法指令用的不多,因为效率很低比较指令CMP(compare)•格式:CMPOPD,OPS•功能:(OPD)—(OPS),跟减法指令很像,但是不存结果•说明:目的操作数减去源操作数......
  • P1306 斐波那契公约数
    P1306斐波那契公约数对于Fibonacci数列:\[f_i=\begin{cases}[i=1]&i\leq1\\f_{i-1}+f_{i-2}&i\gt1\end{cases}\]请求出\(f_n\)与\(f_m\)的最大公约数,即\(\gcd(f_n,f_m)\)。数据规模与约定对于\(100\%\)的数据,保证\(1\l......
  • P3066 [USACO12DEC] Running Away From the Barn G
    P3066[USACO12DEC]RunningAwayFromtheBarnG题目描述给定一颗\(n\)个点的有根树,边有边权,节点从\(1\)至\(n\)编号,\(1\)号节点是这棵树的根。再给出一个参数\(t\),对于树上的每个节点\(u\),请求出\(u\)的子树中有多少节点满足该节点到\(u\)的距离不大于\(t\)。......
  • 龙哥量化:TB交易开拓者_趋势跟踪策略_多策略对单品种_A00011880206期货量化策略,不用过
    写在前面,做自动交易的宽客们都在寻找圣杯,目前,我找到一只玻璃杯,经过半年的漫长等待,玻璃杯没让我失望。路漫漫其修远兮,吾将上下而求索。如果您需要代写技术指标公式,请联系我。龙哥QQ:591438821龙哥微信:Long622889也可以把您的通达信,文华技术指标改成TB交易开拓者(金字塔、文华8......