汇编-代码解释集合

来源:互联网 发布:为什么说网络三大邪书 编辑:程序博客网 时间:2024/05/16 10:08

【汇编代码】

extern:EXTERN 伪操作告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。如果本源文件没有实际引用该符号,该符号将不会被加入到本源文件的符号表中。

global:关键字,把符号导出到其他模块中。global是extern的对立面,如果一个模块声明一个extern的符号,然后引用它,为了防止链接错误,另外某一个模块必须确实定义了该符号,然后把它声明为global。
  1.由于在bar.c中用到函数myprint(),所以要用关键字global将其导出
  2.由于用到本文件外定义的函数choose(),所以要用关键字extern声明
  3.myprint()和choose()遵循的都是C调用约定,后面的参数先入栈,并由调用者清理堆栈

equ:表达式赋值操作符,在某些时候程序中多次出现同一个表达式,为方便起见,用赋值伪操作给表达式赋予一个名字。

int 0x80:系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。通过int 0x80,就可使用内核资源。系统调用是通过int 0x80来实现的,eax寄存器中为调用的功能号,ebx、ecx、edx、esi等等寄存器则依次为参数,exit的功能号_NR_exit为1,write(_NR_write)功能号为4,ebx为文件描述符,stdout的文件描述符为1,ecx则为buffer的内存地址,edx为buffer长度。ebx为0表示返回0。
系统调用的参数传递规则:http://blog.csdn.net/m2o2o2d/article/details/21648777

org:orihin缩写,表示起始地址,源。在汇编语言源程序的开始通常都用一条ORG伪指令来实现规定程序的起始地址。如果不用ORG规定则汇编得到的目标程序将从0000H开始。

mov:数据传送指令,把源位置一个字节、字或双字的操作数复制到目的位置。可以是立即数到通用寄存器,也可以是通用寄存器和通用寄存器、主存、段寄存器之间的互相传送。
     e.g mov  eax,050ah; 把十六进制数050a传送到通用寄存器eax中。

call:call指令不能实现短转移,除此之外与jmp指令实现转移的原理相同。
    CPU执行call指令时,进行两步操作:
    1.将当前的IP或CS和IP压入栈中;
    2.转移;

jmp:无条件转移指令。

$:地址计数器的值——记录正在被汇编程序翻译的语句地址。每个段均分配一个计数器,段内定义的所有标号和变量的偏移地址就是当前汇编地址计数器的值。

$$:表示一个节(一段代码)的开始处被汇编后的地址。(在《Ubuntu下用bochs编译简单操作系统》中即为0x7c00) 

$-$$:经常被用到,表示本行距离程序开始处的相对距离。

int 10h:显示中断,用它可以随意控制屏幕,显示字符、画图等。

ret:用栈中的数据修改IP值,实现近转移。不带任何参数时,用在子程序的结束位置,被调用的子程序必须有ret指令,否则调用没有ret指令的子程序会导致自陷,子程序执行完后处于完全失控状态。带参数ret n表示子程序返回主程序的同时,堆栈弹出n个字节。

times:重复汇编,在times后跟着的表达式会被重复汇编指定次数。

方括号[ ]:在NASM中,任何不被方括号[ ]括起来的标签或变量名都被认为是地址

  mov ax,foo   ;将把foo的地址传给ax

  mov bx,[foo]  ;将把bx的值赋为1

【伪操作】

汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示或伪操作。
符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理之后,所有的符号都被替换成它所代表的地址值。

.section:指示把代码划分成若干个段,程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。

.global:告诉汇编器,_start这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号,_start就像C程序的main函数一样特殊,是整个程序的入口,链接器在链接时会查找目标文件中的_start符号代表的地址,把它设置为整个程序的入口地址,所以每个汇编程序都要提供一个_start符号并且用.globl声明。如果一个符号没有用.globl声明,就表示这个符号不会被链接器用到。

.data:.data段保存程序的数据,是可读可写的,相当于C的全局变量。

.text:.text段保存代码,是只读和可执行的,后面那些指令都属于这个.text段。

_start:是一个符号。

db:伪指令——定义字节。其后的每个操作数占用一个字节。若是字符串, 必须用引号' '括起来,字符串不能超过 255个字符,字符串自左至右以字符的ASCII码按地址递增的顺序依次存放。 

dw:伪指令——定义字。其后的每个操作数占用一个字(低字节在前,高字节在后)。DW可以给两个字符组成的字符串(用' '括起来) 分配两个字节的存储单元(前一个字符在高字节)。DW还可以把其后的变量或标号的偏移地址存入存储器的指定单元(即DW前的变量)。 

dd:伪指令——定义双字。其后的每个操作数占用二个字(低字在前)。 DD还可以把其后的变量或标号的偏移地址和所在段首址存入存储器内指定 的双字单元(即DD前面的变量)中,第一个字中存放DD后的变量的偏移地址, 第二个字中存放该变量所在段的段首址。

push:入栈操作,遵守FILO原则(first in last out),而且必须是字操作。

dword:是双字,也就是32位,可以用来储存32位整数或者32位内存地址。
byte是字节,也就是8位,用来储存char或者char类型指针。
word是字,也就是16位。用来储存16位整数或者16位地址。

add:操作数相加。ADD OPRD1,OPRD2。
   1.OPRD1为任一通用寄存器或存储器操作数,可以是任意一个通用寄存器,而且还可以是任意一个存储器操作数。
   2.OPRD2为立即数,也可以是任意一个通用寄存器操作数.立即数只能用于源操作数。
   3.OPRD1和OPRD2均为寄存器是允许的,一个为寄存器而另一个为存储器也是允许的, 但不允许两个都是存储器操作数。
   4.加法指令运算的结果对CF、SF、OF、PF、ZF、AF都会有影响.以上标志也称为结果标志.加法指令适用于无符号数或有符号数的加法运算。

【命令行】

-s:strip,去掉符号表等内容,可起到对生成的可执行代码减肥的功效(nasm)

ls:列出当前目录下的所有文件

ld:把一定量的目标文件跟档案文件连接起来,并重定位它们的数据,连接符号引用。

bximage:启动bochs创建镜像的程序。(bochs)
fd:选择镜像类型为fd(floppy disk,软盘)。
1.44:选择镜像的大小(1.44M大小的虚拟磁盘软盘文件)。
a.img:为镜像命名。

dd:将操作系统写入软盘,可用于备份、制作USB启动盘。
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc:if代表输入文件,of代表输出设备,bs代表一个扇区大小,count代表扇区数,conv代表不作其它处理。

display_library:bochs使用的GUI库,用来实现Bochs VGA的代码,在Ubuntu下是sdl,Windows下是win32。(配置bochs)
megs:虚拟机内存大小。
floppya:虚拟机外设,软盘为a.img文件。
boot:虚拟机启动方式,从软盘启动。

-o:指定输出文件的文件名

-f:指定输出文件格式(nasm)

-d:预定义一个宏。e.g.  -dF00=100 → %define  F00  100

-c:只编译,生成中间文件(gcc)

生成的.o文件必须都是32位或者都是64位:
-------------------------------------gcc 命令行参数:
-m32:生成32位代码
-m64:生成64位代码
-------------------------------------连接时版本注明:
-m elf_i386 :32位
-m elf_x86_64:
-m elf32_x86_64:
-------------------------------------编译时版本注明:
-f elf64:64位
-f elf32:32位

【其他】

---------------//转移

短转移(short):偏移量在[-128,127]范围内(段内转移,改变指令指针寄存器IP的值)
近转移(near):偏移量在[-32K,32K]范围内(段内转移,改变指令指针寄存器IP的值)
远转移(far):在不同的代码段之间转移(段间转移,改变指令指针寄存器IP的值和代码段寄存器CS的值)
短转移包含在近转移内,但这种包含是以浪费为代价的,短转移指令占的字节少于近转移指令。

---------------//通用寄存器

8086有14个16位寄存器:8个通用寄存器、1个指令指针寄存器、1个标志寄存器和4个段寄存器。它们都有名称,编程时使用其名称代表其保存的内容。
    * AX――累加器(Accumulator),使用频度最高
    * BX――基址寄存器(Base Register),常存放存储器地址
    * CX――计数器(Count Register),常作为计数器
    * DX――数据寄存器(Data Register),存放数据
8086的4个16位数据寄存器:AX、BX、CX、DX,都还可以分为高(H:High)、低(L:low)两个独立的8位寄存器,分别取名为AH / AL、BH / BL、CH / CL、DH / DL;对其中某8位的操作,并不影响另外对应8位的数据。
所以,我们说8086有8个通用的16位寄存器,还有8个通用的8位寄存器。
    * SI――源变址寄存器(Source Index),常保存存储单元地址
    * DI――目的变址寄存器(Destination Index),常保存存储单元地址
    * BP――基址指针寄存器(Base Pointer),表示堆栈区域中的基地址
    * SP――堆栈指针寄存器(Stack Pointer),指示堆栈区域的栈顶地址
    * IP――指令指针寄存器(Instruction Pointer),指示要执行指令所在存储单元的地址。IP寄存器是一个专用寄存器。

---------------//引导扇区

引导扇区512字节,最后必须以结束标志0xaa55结束,结束标志在二进制文件中为“55aa”,后面的数先进入。

0 0
原创粉丝点击