《汇编语言》--程序范例
<p>参考资料:</p><p>《汇编语言程序设计》 Richard Blum 著</p>
<p> </p>
<p>一. 编写程序查看CPUID指令生成的厂商ID字符串</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">.section .data
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">output:
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> .ascii <span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">The processor Vendor ID is 'xxxxxxxx'\n'"</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">.section .text
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">.globl _start
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">_start:
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> movl $<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, %eax
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)"> cpuid
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">movl $output, %edi
</span><span style="color: rgba(0, 128, 128, 1)">10</span> movl %ebx, <span style="color: rgba(128, 0, 128, 1)">28</span><span style="color: rgba(0, 0, 0, 1)">(%edi)
</span><span style="color: rgba(0, 128, 128, 1)">11</span> movl %edx, <span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">(%edi)
</span><span style="color: rgba(0, 128, 128, 1)">12</span> movl %ecx, <span style="color: rgba(128, 0, 128, 1)">36</span><span style="color: rgba(0, 0, 0, 1)">(%edi)
</span><span style="color: rgba(0, 128, 128, 1)">13</span> movl $<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">, %eax
</span><span style="color: rgba(0, 128, 128, 1)">14</span> movl $<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">, %ebx
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">movl $output, %ecx
</span><span style="color: rgba(0, 128, 128, 1)">16</span> movl $<span style="color: rgba(128, 0, 128, 1)">42</span><span style="color: rgba(0, 0, 0, 1)">, %edx
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">int $0x80
</span><span style="color: rgba(0, 128, 128, 1)">18</span> movl $<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">, %eax
</span><span style="color: rgba(0, 128, 128, 1)">19</span> movl $<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, %ebx
</span><span style="color: rgba(0, 128, 128, 1)">20</span> int $0x80</pre>
</div>
<p>这部分代码包含很多汇编指令, 具体的用法后面章节会细细道来, 今天主要是利用这个示例来讲解整个汇编编译,运行,链接,调试以及连接C库函数</p>
<p>二. 下面对源码如何工作的进行简单讲解:</p>
<p>首先, 在数据段声明一个字符串</p>
<pre><span style="color: rgba(0, 128, 128, 1)"> <span style="color: rgba(0, 0, 0, 1)">output:
<span style="color: rgba(0, 128, 128, 1)"> .ascii <span style="color: rgba(128, 128, 128, 1)">"<span style="color: rgba(128, 128, 128, 1)">The processor Vendor ID is 'xxxxxxxx'\n'"<br></span></span></span></span></span></pre>
<pre>.ascii声明使用的是ASCII字符声明一个文本字符串,字符串被预定义并放在内存中,起始位置由output指示<br>下面是程序模板的段落,声明程序的指令码段和一般的起始标签:<br><span style="color: rgba(0, 128, 128, 1)"><span style="color: rgba(0, 0, 0, 1)">.section .text <br><span style="color: rgba(0, 128, 128, 1)"><span style="color: rgba(0, 0, 0, 1)">.globl _start<br><span style="color: rgba(0, 128, 128, 1)"><span style="color: rgba(0, 0, 0, 1)">_start:<br><br>程序做的第一件事就是给EAX寄存器加载零值,然后运行CPUID指令:<br></span></span></span></span></span></span> movl $<span style="color: rgba(128, 0, 128, 1)">0<span style="color: rgba(0, 0, 0, 1)">, %eax</span></span><br><span style="color: rgba(0, 0, 0, 1)"> cpuid</span><br>EAX中的零值定义CPUID输出选项(厂商ID),CPUID运行之后,必须收集分散在三个输出寄存器中的指令响应<br><span style="color: rgba(0, 128, 128, 1)"> <span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 204, 255, 1)">movl $output, %edi-> 创建一个指针声明变量output,output内存加位置加载到EDI寄存器中</span><br><span style="color: rgba(0, 128, 128, 1)"> 接下来按照EDI指针,包含厂商ID字符串的三个寄存器的内容被放到内存数据中的正确位置,括号外的数字表示相对于output标签的放置数据的位置<br> 数字和EDI寄存器中地址相加,就是值被写入的地址<br> <span style="color: rgba(255, 0, 0, 1)">注意:厂商ID 字符串按照奇怪的EBX EDX 和 ECX分散存放</span><br> movl %ebx, <span style="color: rgba(128, 0, 128, 1)">28<span style="color: rgba(0, 0, 0, 1)">(%edi)<br><span style="color: rgba(0, 128, 128, 1)"> movl %edx, <span style="color: rgba(128, 0, 128, 1)">32<span style="color: rgba(0, 0, 0, 1)">(%edi)<br><span style="color: rgba(0, 128, 128, 1)"> movl %ecx, <span style="color: rgba(128, 0, 128, 1)">36<span style="color: rgba(0, 0, 0, 1)">(%edi)<br>在内存中放置好厂商ID字符串之后,就可以显示信息了:<br><span style="color: rgba(0, 128, 128, 1)">movl $<span style="color: rgba(128, 0, 128, 1)">4<span style="color: rgba(0, 0, 0, 1)">, %eax<span style="color: rgba(0, 128, 128, 1)"><br>movl $<span style="color: rgba(128, 0, 128, 1)">1<span style="color: rgba(0, 0, 0, 1)">, %ebx<span style="color: rgba(0, 128, 128, 1)"><br><span style="color: rgba(0, 0, 0, 1)">movl $output, %ecx <br><span style="color: rgba(0, 128, 128, 1)">movl $<span style="color: rgba(128, 0, 128, 1)">42<span style="color: rgba(0, 0, 0, 1)">, %edx<br><span style="color: rgba(0, 128, 128, 1)"><span style="color: rgba(0, 0, 0, 1)">int $0x80</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br>使用系统调用(int $0x80)从linux 内核显示到控制台</pre>
<pre><span style="color: rgba(0, 128, 128, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 128, 128, 1)"><span style="color: rgba(128, 128, 128, 1)"><span style="color: rgba(128, 128, 128, 1)">编译链接:<br></span></span></span></span></span></pre>
<div class="cnblogs_code">
<pre>as -<span style="color: rgba(0, 0, 0, 1)">o cpuid.o cpuid.s
ld </span>-s -o cpuid cpuid.o </pre>
</div>
<pre></pre>
<p>运行结果:The processor Vendor ID is 'GenuineIntel'</p>
<p> </p>
<p>三. 调试程序</p>
<p>使用GDB,为了能够调试汇编代码,需要编译时候添加-gstabs选项</p>
<pre>as -gstabs -<span style="color: rgba(0, 0, 0, 1)">o cpuid.o cpuid.s
ld -s -o cpuid cpuid.o<br><br>3.1 单步运行<br></span></pre>
<div class="cnblogs_code">
<pre>GNU gdb (Ubuntu <span style="color: rgba(128, 0, 128, 1)">7.7</span>.<span style="color: rgba(128, 0, 128, 1)">1</span>-0ubuntu5~<span style="color: rgba(128, 0, 128, 1)">14.04</span>.<span style="color: rgba(128, 0, 128, 1)">2</span>) <span style="color: rgba(128, 0, 128, 1)">7.7</span>.<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
Copyright (C) </span><span style="color: rgba(128, 0, 128, 1)">2014</span><span style="color: rgba(0, 0, 0, 1)"> Free Software Foundation, Inc.
License GPLv3</span>+: GNU GPL version <span style="color: rgba(128, 0, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">or</span> later <http://gnu.org/licenses/gpl.html><span style="color: rgba(0, 0, 0, 1)">
This </span><span style="color: rgba(0, 0, 255, 1)">is</span> free software: you are free to change <span style="color: rgba(0, 0, 255, 1)">and</span><span style="color: rgba(0, 0, 0, 1)"> redistribute it.
There </span><span style="color: rgba(0, 0, 255, 1)">is</span> NO WARRANTY, to the extent permitted by law.Type <span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">show copying"</span>
<span style="color: rgba(0, 0, 255, 1)">and</span> <span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">show warranty" for details.</span>
This GDB was configured as <span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">x86_64-linux-gnu".</span>
Type <span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">show configuration" for configuration details.</span>
<span style="color: rgba(0, 0, 0, 1)">For bug reporting instructions, please see:
</span><http://www.gnu.org/software/gdb/bugs/><span style="color: rgba(0, 0, 0, 1)">.
Find the GDB manual </span><span style="color: rgba(0, 0, 255, 1)">and</span><span style="color: rgba(0, 0, 0, 1)"> other documentation resources online at:
</span><http://www.gnu.org/software/gdb/documentation/><span style="color: rgba(0, 0, 0, 1)">.
For help, type </span><span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">help".</span>
Type <span style="color: rgba(128, 128, 128, 1)">"</span><span style="color: rgba(128, 128, 128, 1)">apropos word" to search for commands related to "word"...</span>
Reading symbols from cpuid...(no debugging symbols found)...done.</pre>
</div>
<pre></pre>
<p>使用RUN指令运行</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">(gdb) run
Starting program: </span>/home/fly/smem-<span style="color: rgba(128, 0, 128, 1)">0.1</span>/huibian/<span style="color: rgba(0, 0, 0, 1)">cpuid
The processor Vendor </span><span style="color: rgba(0, 0, 255, 1)">ID</span> <span style="color: rgba(0, 0, 255, 1)">is</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 128, 0, 1)">GenuineIntel.s</span></pre>
</div>
<p>基本调试命令与调试C类似,这里不做讲解了</p>
<p>3.2 查看数据</p>
<p>info register: 显示所有寄存器的值</p>
<p>print: 显示特定寄存器或者程序变量的值</p>
<p>x: 显示特定内存位置的内容</p>
<p>使用info reginster 查看指令如何影响所有寄存器是很方便的:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">(gdb) info registers
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> rax <span style="color: rgba(128, 0, 128, 1)">0x4</span> <span style="color: rgba(128, 0, 128, 1)">4</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> rbx <span style="color: rgba(128, 0, 128, 1)">0x1</span> <span style="color: rgba(128, 0, 128, 1)">1</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> rcx <span style="color: rgba(128, 0, 128, 1)">0x6000ec</span> <span style="color: rgba(128, 0, 128, 1)">6291692</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> rdx <span style="color: rgba(128, 0, 128, 1)">0x2a</span> <span style="color: rgba(128, 0, 128, 1)">42</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> rsi <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> rdi <span style="color: rgba(128, 0, 128, 1)">0x6000ec</span> <span style="color: rgba(128, 0, 128, 1)">6291692</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> rbp <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0x0</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> rsp <span style="color: rgba(128, 0, 128, 1)">0x7fffffffeb10</span> <span style="color: rgba(128, 0, 128, 1)">0x7fffffffeb10</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> r8 <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> r9 <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> r10 <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> r11 <span style="color: rgba(128, 0, 128, 1)">0x200</span> <span style="color: rgba(128, 0, 128, 1)">512</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> r12 <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> r13 <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> r14 <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> r15 <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> rip <span style="color: rgba(128, 0, 128, 1)">0x4000dc</span> <span style="color: rgba(128, 0, 128, 1)">0x4000dc</span> <_start+<span style="color: rgba(128, 0, 128, 1)">44</span>>
<span style="color: rgba(0, 128, 128, 1)">19</span> eflags <span style="color: rgba(128, 0, 128, 1)">0x10202</span><span style="color: rgba(0, 0, 0, 1)"> [ IF RF ]
</span><span style="color: rgba(0, 128, 128, 1)">20</span> cs <span style="color: rgba(128, 0, 128, 1)">0x33</span> <span style="color: rgba(128, 0, 128, 1)">51 </span>
<span style="color: rgba(0, 128, 128, 1)">21</span> ss <span style="color: rgba(128, 0, 128, 1)">0x2b</span> <span style="color: rgba(128, 0, 128, 1)">43</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> ds <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">23</span> es <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> fs <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span>
<span style="color: rgba(0, 128, 128, 1)">25</span> gs <span style="color: rgba(128, 0, 128, 1)">0x0</span> <span style="color: rgba(128, 0, 128, 1)">0</span></pre>
</div><br><br>
来源:https://www.cnblogs.com/mysky007/p/11055970.html
頁:
[1]