<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://www.gentoo-zh.org/extern.php?action=feed&amp;tid=283&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Gentoo中文社区 / 汇编语言程序设计]]></title>
		<link>https://www.gentoo-zh.org/viewtopic.php?id=283</link>
		<description><![CDATA[汇编语言程序设计 最近发表的帖子。]]></description>
		<lastBuildDate>Thu, 25 Aug 2022 05:01:26 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[汇编语言程序设计]]></title>
			<link>https://www.gentoo-zh.org/viewtopic.php?pid=289#p289</link>
			<description><![CDATA[<p>程序设计</p><p>&#160; &#160; &#160; &#160; 汇编语言源程序<br />&#160; &#160; &#160; &#160; &#160; &#160; 汇编语言源程序的结构<br />&#160; &#160; &#160; &#160; &#160; &#160; 表达式<br />&#160; &#160; &#160; &#160; &#160; &#160; 伪指令<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 格式<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 操作数<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 重复操作符<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 段定义伪指令<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 设定段寄存器伪指令</p><p>汇编语言源程序<br />汇编语言源程序的结构</p><p>一个完整的源程序通常由若干逻辑段组成，包括数据段、附加段、堆栈段和代码段。它们分别映射到存储器中的物理段上。每个逻辑段以segment语句开始，以ends结束，整个源程序用end语句结尾。</p><p>代码段中存放源程序的所有指令码、数据、变量等则放在数据段和附加段中。程序中可以定义堆栈段，也可以直接利用系统中的堆栈段。具体一个源程序中要定义多少个段应根据实际需求来定。</p><p>dseg segment ;定义数据段<br />&#160; &#160; data1 dw 0f865h ;DW是定义2字节空间<br />&#160; &#160; data2 dw 360ch<br />dseg ends</p><p>eseg segment ;定义附加段<br />&#160; &#160; sum dw 2 dup(?) ;定义存放结果<br />eseg ends</p><p>cseg segment ;定义代码段<br />&#160; &#160; assume cs:cseg,ds:dseg,es:eseg<br />start:mov ax,dseg<br />&#160; &#160; &#160; mov ds,ax ;初始化DS<br />&#160; &#160;&#160; &#160;mov ax,eseg<br />&#160; &#160;&#160; &#160;mov es,ax ;初始化ES<br />&#160; &#160;&#160; &#160;lea si,sum ;存放结果的偏移地址送SI<br />&#160; &#160;&#160; &#160;mov ax,data1 ;取被加数<br />&#160; &#160;&#160; &#160;add ax,data2 ;两数相加<br />&#160; &#160;&#160; &#160;mov es:[si],ax ;和送附加段的sum<br />&#160; &#160;&#160; &#160;hlt<br />cseg ends<br />&#160; &#160; end start</p><p>表达式</p><p>表达式不是一个指令，本身不能执行，在程序汇编时，汇编程序将表达式进行相应的运算，得出一个确定的值。</p><p>&#160; &#160; +-*/：当运符作为一个数值表达式时，其汇编结果就是一个数值。</p><p>&#160; &#160; 逻辑运算符：只用于数值表达式，用于对数值进行位运算并得到一个结果。</p><p>&#160; &#160; 关系运算符：有六个，EQ（相等），NE（不相等）,LT(小于)，GT（大于），LE（小于等于），GE（大于等于）。</p><p>&#160; &#160; 取值运算符和属性运算符<br />&#160; &#160; &#160; &#160; OFFSET：可以得到一个标号或变量的偏移地址。例如：mov si,offset data1将变量data1的偏移地址送si。与lea si,data1执行结果相同。<br />&#160; &#160; &#160; &#160; SEG：利用运算符可以得到一个标号或变量的段地址。例如：mov ax,seg data<br />&#160; &#160; &#160; &#160; PTR：属性运算符用来指定定位于其后的存储器操作数的类型。call dword ptr[bx]说明存储器操作数为4个字节，即调用远程。</p><p>伪指令<br />格式</p><p>[变量] 伪操作 操作数，[操作数...]，常用数据定义伪指令有以下5种。</p><p>&#160; &#160; DB：定义变量为字节类型，变量中的每个操作数占一个字节，DB伪指令也常用来定义字符串。<br />&#160; &#160; DW：定义变量为字类型，DW伪指令后面的操作数都占2个字节，在内存中存放时，低字节放到低地址。<br />&#160; &#160; DD：定义变量为双字节类型，DD伪指令后面的每个操作数都占用4个字节，在内存中存放时，同样是低字节发放到低地址。<br />&#160; &#160; DQ：定义变量为四字类型，在内存中存放。<br />&#160; &#160; DT：定义变量为十字节类型，在内存中存放。</p><p>操作数</p><p>data db 11h,33h ;定义包含两个元素的字节变量data<br />num dw 100*5+88 ;定义一个字类型，其初值为表达式的值<br />str db &#039;hello!&#039; ;定义一个字符串，首地址为str<br />sum dq 0011223344556677h ;将4个字存入sum，它们在内存中的存放由低到高为77h,66h,55h,44h<br />data2 dw ? ;为变量data2分配2个字节的空间，初值为任意值</p><br /><p>重复操作符</p><p>[变量名] 数据定义伪操作 n dup(初值,[初值...])，圆括号中为重复的内容，n为重复的次数，如果用n dup(?)作为数据定义伪操作的唯一操作数，则汇编程序仅保留n个元素大小的数据区。</p><p>data1 db 20 dup(?) ;为变量data1分配20个字节的空间，初值为任意值。<br />data2 db 20 dup(30h) ;为变量data2分配20个字节的空间，初值均为30h</p><p>段定义伪指令</p><p>段名 segment [定位类型][组合类型][&#039;类别&#039;]<br />...<br />段名 ends</p><br /><p>定位类型</p><p>&#160; &#160; para：说明逻辑段从一个字节的边界开始，16个字节为一个节，所以段的起始地址应能被16整除，也就是起始的物理地址为xxxx0h。<br />&#160; &#160; byte：说明逻辑段从字节边界开始，即可以从任何地址开始，此时本段的起始地址紧接在前一个段的后面。<br />&#160; &#160; word：说明逻辑段从字边界开始，即本段的起始地址必须是偶数。<br />&#160; &#160; page：说明逻辑段从页边界开始，256字节为一页，故本段起始物理地址为xxx00h。</p><p>组合类型</p><p>&#160; &#160; none：表示本段与其他逻辑段不组合。即对不同程序模块中的逻辑段，即使具有相同的段名，也分别作为不同的逻辑段装入内存而不进行组合。<br />&#160; &#160; public：表示对于不同程序模块中用public说明的具有相同段名的逻辑段，汇编将它们组合到一起，构成一个大的逻辑段。<br />&#160; &#160; stack：组合类型为stack时，其含义和public基本相同，但仅限于堆栈段使用。<br />&#160; &#160; common：表示不同程序模块中用common说明的同名逻辑段，连接时从同一个地址开始装入，即各个逻辑段重叠一起。连接之后的段长度等于原来最长的逻辑段长度。<br />&#160; &#160; memory：表示当几个逻辑段连接时，本逻辑段定位在地址最高的地方。如果被连接的逻辑段中有多个段的组合类型都是memory，则汇编程序只将首先遇到的段作为memory，而其余的都作为common处理。</p><p>设定段寄存器伪指令</p><p>assume伪指令用于向汇编程序说明所定义的逻辑段属于何种类型的逻辑段。说明方法是将逻辑段的短命和对应的段寄存器联系起来。一般格式为assume 段寄存器名:段名,[段寄存器:段名]。</p><p>; 程序功能：10ms延时的子程序<br />delay proc ;定义一个子过程 proc的作用是子程序定义伪指令<br />&#160; &#160;&#160; &#160;push bx ;保护原有bx内容<br />&#160; &#160;&#160; &#160;push cx ;保存原有cx内容<br />&#160; &#160;&#160; &#160;mov bl,2 ;外循环次数<br />next: mov cx,4167 ;内循环次数（延时5ms）<br />w10ms:loop w10ms ;cx不等于0时则循环<br />&#160; &#160;&#160; &#160;dec bl ;修改外循环计数值<br />&#160; &#160;&#160; &#160;jnz next ;BX不为0时则进行第二轮循环<br />&#160; &#160;&#160; &#160;pop cx ;恢复cx值。<br />&#160; &#160;&#160; &#160;pop bx ;恢复bx值。<br />&#160; &#160;&#160; &#160;ret ;过程返回<br />delay endp</p>]]></description>
			<author><![CDATA[dummy@example.com (batsom)]]></author>
			<pubDate>Thu, 25 Aug 2022 05:01:26 +0000</pubDate>
			<guid>https://www.gentoo-zh.org/viewtopic.php?pid=289#p289</guid>
		</item>
	</channel>
</rss>
