-
Notifications
You must be signed in to change notification settings - Fork 25
/
ch18s04.html
3 lines (3 loc) · 4.92 KB
/
ch18s04.html
1
2
3
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>4. 寻址方式</title><link rel="stylesheet" href="styles.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="Linux C编程一站式学习" /><link rel="up" href="ch18.html" title="第 18 章 x86汇编程序基础" /><link rel="prev" href="ch18s03.html" title="3. 第二个汇编程序" /><link rel="next" href="ch18s05.html" title="5. ELF文件" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">4. 寻址方式</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch18s03.html">上一页</a> </td><th width="60%" align="center">第 18 章 x86汇编程序基础</th><td width="20%" align="right"> <a accesskey="n" href="ch18s05.html">下一页</a></td></tr></table><hr /></div><div class="sect1" lang="zh-cn" xml:lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id2770425"></a>4. 寻址方式</h2></div></div></div><p>通过上一节的例子我们了解到,访问内存时在指令中可以用多种方式表示内存地址,比如可以用数组基地址、元素长度和下标三个量来表示,增加了寻址的灵活性。本节介绍x86常用的几种寻址方式(Addressing Mode)<a id="id2770436" class="indexterm"></a>。内存寻址在指令中可以表示成如下的通用格式:</p><div class="literallayout"><p>ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER)</p></div><p>它所表示的地址可以这样计算出来:</p><div class="literallayout"><p>FINAL ADDRESS = ADDRESS_OR_OFFSET + BASE_OR_OFFSET + MULTIPLIER * INDEX</p></div><p>其中ADDRESS_OR_OFFSET和MULTIPLIER必须是常数,BASE_OR_OFFSET和INDEX必须是寄存器。在有些寻址方式中会省略这4项中的某些项,相当于这些项是0。</p><div class="itemizedlist"><ul type="disc"><li><p>直接寻址(Direct Addressing Mode)<a id="id2770476" class="indexterm"></a>。只使用ADDRESS_OR_OFFSET寻址,例如<code class="literal">movl ADDRESS, %eax</code>把ADDRESS地址处的32位数传送到<code class="literal">eax</code>寄存器。</p></li><li><p>变址寻址(Indexed Addressing Mode)<a id="id2770501" class="indexterm"></a> 。上一节的<code class="literal">movl data_items(,%edi,4), %eax</code>就属于这种寻址方式,用于访问数组元素比较方便。</p></li><li><p>间接寻址(Indirect Addressing Mode)<a id="id2770521" class="indexterm"></a>。只使用BASE_OR_OFFSET寻址,例如<code class="literal">movl (%eax), %ebx</code>,把<code class="literal">eax</code>寄存器的值看作地址,把内存中这个地址处的32位数传送到<code class="literal">ebx</code>寄存器。注意和<code class="literal">movl %eax, %ebx</code>区分开。</p></li><li><p>基址寻址(Base Pointer Addressing Mode)<a id="id2770560" class="indexterm"></a>。只使用ADDRESS_OR_OFFSET和BASE_OR_OFFSET寻址,例如<code class="literal">movl 4(%eax), %ebx</code>,用于访问结构体成员比较方便,例如一个结构体的基地址保存在<code class="literal">eax</code>寄存器中,其中一个成员在结构体内的偏移量是4字节,要把这个成员读上来就可以用这条指令。</p></li><li><p>立即数寻址(Immediate Mode)<a id="id2770588" class="indexterm"></a>。就是指令中有一个操作数是立即数,例如<code class="literal">movl $12, %eax</code>中的<code class="literal">$12</code>,这其实跟寻址没什么关系,但也算作一种寻址方式。</p></li><li><p>寄存器寻址(Register Addressing Mode)<a id="id2770614" class="indexterm"></a>。就是指令中有一个操作数是寄存器,例如<code class="literal">movl $12, %eax</code>中的<code class="literal">%eax</code>,这跟内存寻址没什么关系,但也算作一种寻址方式。在汇编程序中寄存器用助记符来表示,在机器指令中则要用几个Bit表示寄存器的编号,这几个Bit也可以看作寄存器的地址,但是和内存地址不在一个地址空间。</p></li></ul></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch18s03.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="ch18.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="ch18s05.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">3. 第二个汇编程序 </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 5. ELF文件</td></tr></table></div></body></html>