8086 asm文件语法-2
Posted 不会写代码的丝丽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8086 asm文件语法-2相关的知识,希望对你有一定的参考价值。
无条件跳转
jmp short 标号
段内跳,仅能跳转单个字节长度范围(255)
data_seg segment
g_szSrc db "abcde$"
g_szDst db 255 dup(0cch)
data_seg ends
code segment
START:
assume ds:data_seg
mov ax,data_seg
;放入ds到正确位置
mov ds,ax
;不加 short 也是可以的
jmp short LABLE1
mov ax,ax
LABLE1:
mov bx,bx
;不加near ptr 也是可以的 但是不能写 short否则编译报错
jmp LABLE2
db 256 dup(01h)
mov bx,bx
LABLE2:
mov bx,bx
code ends
end START
上面代码我们运行下:
执行到跳转前
执行跳转后
我们来编译一个错误的示例:
data_seg segment
g_szSrc db "abcde$"
g_szDst db 255 dup(0cch)
data_seg ends
code segment
START:
mov bx,bx
;强制声明为单字节跳转但是lable2的地址超过255因此会报错
jmp short LABLE2
db 256 dup(01h)
mov bx,bx
LABLE2:
mov bx,bx
code ends
end START
jmp near ptr 标签
段内跳,仅能跳转2个字节长度范围(65535)
参考jmp short
jmp far ptr 标签
可以跨段跳,会修改cs和ip数值
data_seg segment
g_szSrc db "abcde$"
g_szDst db 255 dup(0cch)
data_seg ends
code_seg2 segment
LABLE:
mov si,si
code_seg2 ends
code segment
START:
assume ds:data_seg
mov ax,data_seg
mov bx,code_seg2
jmp far ptr LABLE
code ends
end START
通过寄存器跳转
code segment
START:
assume ds:data_seg
lea ax,LABLE2
jmp ax
LABLE2:
mov ax,ax
code ends
end START
通过EA跳转
段内
从内存中取出2字节进行跳转
- jmp 变量名字
- jmp word ptr [EA]
- jmp near ptr [EA]
data_seg segment
g_szDst dw 0
data_seg ends
code segment
START:
assume ds:data_seg
mov ax,data_seg
mov ds,ax
lea ax,LABLE2
assume ds:data_seg
mov g_szDst,ax
jmp g_szDst
jmp word ptr g_szDst
;下列语句不支持 可以改用另一种比较迂回的方式
; jmp near ptr g_szDst
lea bx,g_szDst
jmp near ptr [bx]
LABLE2:
mov ax,ax
code ends
end START
跨段
从内存中分别取两个字节分别用与修改cs和ip从而完成跨段跳转.前一个字放入ip,后一个字放入cs
- jmp 变量名
- jmp dword ptr [EA]
- jmp far ptr [EA]
data_seg segment
;定义一个双字,注意必须定义双字否则编译器可能视为段内跳转
g_szDst dd 0
data_seg ends
jmp_seg segment
LABLE2:
mov bx,ax
jmp_seg ends
code segment
START:
assume ds:data_seg
mov ax,data_seg
mov ds,ax
lea bx,g_szDst
;第一个字放入到ip所以此处放入段内偏移
mov word ptr [bx],offset LABLE2
;后移动一个字放入段地址
add bx,2
;后一个字作为段地址
mov word ptr[bx],jmp_seg
jmp g_szDst
jmp dword ptr[bx]
jmp far ptr [bx]
code ends
end START
条件跳转
首先我们大致浏览如下表格
举例其中一个用法即可
data_seg segment
;定义一个双字,注意必须定义双字否则编译器可能视为段内跳转
g_szDst dd 0
data_seg ends
code segment
START:
assume ds:data_seg
mov ax,data_seg
mov ds,ax
;让zf标志为1
; xor ax,ax
jz LABLE1
mov bx,bx
LABLE1:
mov ax,ax
code ends
end START
循环
指令 | 重复条件 |
---|---|
LOOP | CX!=0 |
LOOPZ/LOOPE | cx!=0 且 zf ==1 |
LOOPNZ/LOOPNE | cx!=0 且 zf ==0 |
下面我们输出hello world$到屏幕
data_seg segment
;定义一个双字,注意必须定义双字否则编译器可能视为段内跳转
g_szDst db "hello world$"
g_bLen db 0
data_seg ends
code segment
START:
assume ds:data_seg
mov ax,data_seg
mov ds,ax
;设置标志寄存器,目的让lodsb执行后自动si+1
CLD
lea si,g_szDst
;设置cx长度为字符串长度
mov cx,offset g_bLen- offset g_szDst
LOOP_START:
lodsb ;去除一个字符放入al
;调用系统函数此处为输出字符到屏幕
mov dl,al
mov ah,2
int 21h
;自动让cx减一,当cx==0时停止循环
loop LOOP_START
LABLE1:
mov ax,ax
code ends
end START
一个更复杂的例子,改造上面的例子当我们输出字符到o
的时候自动停止输出
data_seg segment
;定义一个双字,注意必须定义双字否则编译器可能视为段内跳转
g_szDst db "hello world$"
g_bLen db 0
data_seg ends
code segment
START:
assume ds:data_seg
mov ax,data_seg
mov ds,ax
;设置标志寄存器,目的让lodsb执行后自动si+1
CLD
lea si,g_szDst
mov cx,offset g_bLen- offset g_szDst
LOOP_START:
lodsb ;去除一个字符放入al
;调用系统函数
mov dl,al
mov ah,2
int 21h
;与o做比较然后影响标志位
cmp al,'o'
;自动让cx减一,当cx!=0且zf!=0继续循环
loopnz LOOP_START
;停止输出
mov ax,4c00h
int 21h
LABLE1:
mov ax,ax
code ends
end START
以上是关于8086 asm文件语法-2的主要内容,如果未能解决你的问题,请参考以下文章