<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Assembly on Blog</title><link>https://blog.sivn.net.cn/tags/assembly/</link><description>Recent content in Assembly on Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Tue, 23 Jun 2026 19:01:07 +0800</lastBuildDate><atom:link href="https://blog.sivn.net.cn/tags/assembly/index.xml" rel="self" type="application/rss+xml"/><item><title>8086汇编-01</title><link>https://blog.sivn.net.cn/post/assembly-basic/</link><pubDate>Tue, 23 Jun 2026 19:01:07 +0800</pubDate><guid>https://blog.sivn.net.cn/post/assembly-basic/</guid><description>&lt;p&gt;注：以下只针对8086实模式，保护模式下略有不同&lt;/p&gt;
&lt;h1 id="寄存器"&gt;寄存器
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;数据寄存器(16bit)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;AX(AH, AL)&lt;/li&gt;
&lt;li&gt;BX(BH, BL): 常用作基数寄存器（即数据段的偏移地址寄存器)&lt;/li&gt;
&lt;li&gt;CX(CH, CL)&lt;/li&gt;
&lt;li&gt;DX(DH, DL)&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;指针寄存器&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;BP:基数指针寄存器&lt;/li&gt;
&lt;li&gt;SP:堆栈指针寄存器，用于堆栈段的偏移地址寄存器&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;变址寄存器&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;SI:源变址寄存器，与BX功能相近，但更常用于变址寻址&lt;/li&gt;
&lt;li&gt;DI:目的变址寄存器，与BX功能相近，但更常用于变址寻址&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;段寄存器&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;CS:代码段寄存器，存放代码段的段地址&lt;/li&gt;
&lt;li&gt;DS:数据段寄存器&lt;/li&gt;
&lt;li&gt;SS:堆栈段寄存器&lt;/li&gt;
&lt;li&gt;ES:附加数据段寄存器,当DS被占用后，可以另外使用ES来充当另一个数据段的寄存器
有时ES段会作为显存使用&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="5"&gt;
&lt;li&gt;其他&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;IP:指令指针寄存器(用于代码段的偏移地址寄存器)&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="6"&gt;
&lt;li&gt;状态标志寄存器
16位，9个标志&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="内存"&gt;内存
&lt;/h1&gt;&lt;p&gt;8086的一个内存单元为8位，1字节。&lt;/p&gt;
&lt;p&gt;对于一个字，8086采用小端模式(little-ending)。
即&lt;strong&gt;一个字的高字节放在高地址，低字节放到低地址&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="段"&gt;段
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;段可重叠&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;8086CPU有20位地址总线，16位数据总线。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;物理地址 = 段寄存器值 × 16 + 偏移地址&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;也就是段基址按 &lt;code&gt;16 字节&lt;/code&gt; 对齐，而偏移地址范围是 &lt;code&gt;0000h&lt;/code&gt; 到 &lt;code&gt;FFFFh&lt;/code&gt;，一个段最大可覆盖 &lt;code&gt;64KB&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;CS:IP(即物理地址为CS*16+IP)指向的指令即为当前正要执行的指令
SS:SP指向栈顶&lt;/p&gt;
&lt;h1 id="指令"&gt;指令
&lt;/h1&gt;&lt;h2 id="数据传输"&gt;数据传输
&lt;/h2&gt;&lt;h3 id="mov"&gt;MOV
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;mov dest, src&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;src赋给dest&lt;/p&gt;
&lt;p&gt;通用寄存器&amp;ndash;&amp;gt;通用寄存器
立即数&amp;ndash;&amp;gt;通用寄存器
立即数&amp;ndash;&amp;gt;内存
内存&amp;ndash;&amp;gt;通用寄存器：MOV AX,DS:[BX]
通用寄存器&amp;ndash;&amp;gt;内存
段寄存器（CS/IP除外）&amp;ndash;&amp;gt;内存
内存&amp;ndash;&amp;gt;段寄存器（CS/IP除外）
段寄存器（CS/IP除外）&amp;ndash;&amp;gt;通用寄存器
通用寄存器&amp;ndash;&amp;gt;段寄存器（CS/IP除外）&lt;/p&gt;
&lt;p&gt;MOV指令不能修改CS/IP的内容&lt;/p&gt;
&lt;p&gt;不能直接把立即数放到段寄存器中&lt;/p&gt;
&lt;h3 id="push-pop"&gt;PUSH, POP
&lt;/h3&gt;&lt;p&gt;入栈，出栈&lt;/p&gt;
&lt;p&gt;栈的格式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;栈顶低地址&lt;/li&gt;
&lt;li&gt;栈底高地址&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PUSH AX&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SP-=2，栈顶指针空出一个字&lt;/li&gt;
&lt;li&gt;将AX的内容放到SS:SP所指的单元(一个字)中，SS:SP重新指向栈顶&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sub sp, 2
mov word ptr [ss:sp], ax
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;PUSH/POP 通用寄存器
PUSH/POP 段寄存器
PUSH/POP 内存单元&lt;/p&gt;
&lt;h3 id="pushfpopf"&gt;PUSHF、POPF
&lt;/h3&gt;&lt;p&gt;标志寄存器入出栈&lt;/p&gt;
&lt;h2 id="算术运算"&gt;算术运算
&lt;/h2&gt;&lt;h3 id="add"&gt;ADD
&lt;/h3&gt;&lt;h3 id="adc"&gt;ADC
&lt;/h3&gt;&lt;p&gt;带进制加法&lt;/p&gt;
&lt;p&gt;dest = dest+src+CF&lt;/p&gt;
&lt;h3 id="inc"&gt;INC
&lt;/h3&gt;&lt;p&gt;increase&lt;/p&gt;
&lt;p&gt;自加1&lt;/p&gt;
&lt;h3 id="sub"&gt;SUB
&lt;/h3&gt;&lt;h3 id="sbb"&gt;SBB
&lt;/h3&gt;&lt;p&gt;带借位减法&lt;/p&gt;
&lt;p&gt;dest = dest-src-CF&lt;/p&gt;
&lt;h3 id="dec"&gt;DEC
&lt;/h3&gt;&lt;p&gt;decrease&lt;/p&gt;
&lt;p&gt;自减&lt;/p&gt;
&lt;h3 id="neg"&gt;NEG
&lt;/h3&gt;&lt;p&gt;negtive&lt;/p&gt;
&lt;p&gt;dest=0-dest&lt;/p&gt;
&lt;h3 id="div"&gt;DIV
&lt;/h3&gt;&lt;p&gt;DIV REG/内存单元&lt;/p&gt;
&lt;p&gt;被除数/除数=商&lt;/p&gt;
&lt;p&gt;除数：可以为8位或者16位，放在寄存器或者内存单元中，在指令的操作数中显式给出。&lt;/p&gt;
&lt;p&gt;被除数：根据除数的位数动态调整：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果除数为8位，则被除数为16位，需提前放在AX中，不用在指令中给出&lt;/li&gt;
&lt;li&gt;如果除数为16位，则被除数为32位，需提前放在DX（高16位）、AX（低16位）中，不需要在指令中给出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;商：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果除数为8位，则商将放到AL中，余数将放到AH中&lt;/li&gt;
&lt;li&gt;如果除数为16位，则商将放到AX中，余数将放到DX中&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mul"&gt;MUL
&lt;/h3&gt;&lt;p&gt;MUL REG/内存单元&lt;/p&gt;
&lt;p&gt;两个数相乘，要么都是8位，要么都是16位。&lt;/p&gt;
&lt;p&gt;如果是8位&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个乘数需要提前放到AL中，无需在指令中给出&lt;/li&gt;
&lt;li&gt;另一个乘数可以放到8位寄存器或者内存单元中，需在指令中给出&lt;/li&gt;
&lt;li&gt;结果默认放到AX中&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果是16位&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个乘数需要提前放到AX中，无需再指令中给出&lt;/li&gt;
&lt;li&gt;另一个乘数可以放到16位寄存器或者内存单元中，需在指令中给出&lt;/li&gt;
&lt;li&gt;结果默认高位放到DX中，低位放到AX中&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="imul"&gt;IMUL
&lt;/h3&gt;&lt;h3 id="cmp"&gt;CMP
&lt;/h3&gt;&lt;p&gt;CMP 对象1,对象2&lt;/p&gt;
&lt;p&gt;执行 对象1 - 对象2 的运算，但不保留运算结果，只是根据运算结果对相应的标志寄存器进行置位&lt;/p&gt;
&lt;h2 id="逻辑"&gt;逻辑
&lt;/h2&gt;&lt;p&gt;AND,OR,NOT,XOR,TEST&lt;/p&gt;
&lt;p&gt;SHL,SHR&lt;/p&gt;
&lt;p&gt;SAL,SAR&lt;/p&gt;
&lt;p&gt;ROL,ROR&lt;/p&gt;
&lt;p&gt;RCL,RCR&lt;/p&gt;
&lt;h2 id="转移"&gt;转移
&lt;/h2&gt;&lt;p&gt;JMP&lt;/p&gt;
&lt;p&gt;JE,JNE,
JB,JNB,
JA,JNA&lt;/p&gt;
&lt;h2 id="其他"&gt;其他
&lt;/h2&gt;&lt;p&gt;LOOP&lt;/p&gt;
&lt;p&gt;RET,RETF&lt;/p&gt;
&lt;p&gt;CALL&lt;/p&gt;
&lt;h2 id="串"&gt;串
&lt;/h2&gt;&lt;p&gt;MOVSB&lt;/p&gt;
&lt;p&gt;MOVSW&lt;/p&gt;
&lt;p&gt;REP&lt;/p&gt;
&lt;p&gt;CLD/STD&lt;/p&gt;
&lt;h2 id="中断"&gt;中断
&lt;/h2&gt;&lt;p&gt;IRET&lt;/p&gt;
&lt;p&gt;INT&lt;/p&gt;
&lt;p&gt;STI/SLI&lt;/p&gt;
&lt;p&gt;INFO&lt;/p&gt;
&lt;h2 id="io"&gt;I/O
&lt;/h2&gt;&lt;p&gt;IN&lt;/p&gt;
&lt;p&gt;OUT&lt;/p&gt;
&lt;h1 id="语法"&gt;语法
&lt;/h1&gt;&lt;p&gt;语法主要分为intel和AT&amp;amp;T&lt;/p&gt;
&lt;p&gt;这里使用intel语法&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据不能以字母开头，如A123H必须写成0A123H&lt;/li&gt;
&lt;li&gt;需要暂存数据时（当寄存器数量不够时），常用堆栈来暂存&lt;/li&gt;
&lt;li&gt;8086CPU中，只有BX、SI、DI、BP可以用来寻址&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是根据编译器不同，语法也有略微差异，
这里以masm为例&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ASSUME CS:CODE,DS:DATA,SS:STACK
;令CODE段与CS寄存器相关联，DATA段与DS寄存器相关联，STACK段与SS寄存器相关联

DATA SEGMENT ;定义DATA段开始
 ....
DATA ENDS ;DATA段结束

STACK SEGMENT ;定义STACK段开始
 ....
STACK ENDS ;STACK段结束
CODE SEGMENT ;定义CODE段开始
START: MOV AX,0123H ;程序从这里开始
 ......

 MOV AX,4C00H
 I NT 21H ;程序返回
CODE ENDS ;CODE段结束
END START;程序结束
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="quote"&gt;quote
&lt;/h1&gt;&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/441362934" target="_blank" rel="noopener"
 &gt;https://zhuanlan.zhihu.com/p/441362934&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>