汇编入门

80386通用寄存器

  • %ax :accumulate 累加寄存器
  • %bx :base 基址寄存器
  • %cx :count 计数寄存器
  • %dx :divide 放除法的商和余数
  • %eax : extend 扩展 表示32位的寄存器
    %eax表示32位寄存器,%ax表示低16位,在低16位的寄存器中:%ah表示高八位,%al表示第八位

汇编指令

1005.s 立即数寻址


movl $8,%eax;

  • $是立即数,表示8
  • movl是移动的意思,将8赋值给%eax;
    最终的运行结果如下

1006.s 寄存器寻址

  • movl 用于传送32位的长子值
  • movw 用于传送16位的子值
  • movb 用于传送8位的子值

    不能把movw的w改为l,因为%bx是16位的寄存器,如果改为l试图把32位的传给16位是错误的。可以写mov / movw

    命令为 movw $0x5678,%dx ; 意思是传16个字节(w)的数据到寄存器dx里,结果如我们所愿,如果用%dh/%dl便会报错,因为%dh/%dl是8位的寄存器;同样,也不能movw $0x5678,%edx,因为edx是32位的,所以只能写32位的地址。如下图,所以要用对应的寄存器和对应位数的mov指令或只写mov去传递数据。

1007.s 绝对寻址(直接寻址)

movl 0x08048054,%exc,直接把这个内存地址赋给%exc。可以使用x/4bx 08048054来查看以8054起的四个地址内容。
查看内存内容

内存之中既可以存放数据,也可以存放指令。如图,b9是指令,从后往前看08、04、80、55就是数据。

1008.s 间接寻址

movl (%ebx),%eax 和寄存器寻址的区别在于第一个寄存器套上了括号,表示不是把寄存器%ebx的值赋给%eax,而是寄存器存放的数据的地址存放的内容赋给%eax。

第一步,立即数寻址,把立即数08048054放到%ecx

第二步,查看08048054内存中存放的数据是什么,并将其传入16位的%ax中,得到结果0x8056,为什么是8056?因为56是低位,80是高位

1009.s 变址寻址

movl (%ebx,%edx),%eax 在1008的基础上,把括号内两个寄存器的值加起来,用这个内存地址去找里面的数据,然后把数据传给%eax。

1010.s 比例变址寻址

movl (%ebx,%ecx,0x2),%eax
%ebx为基址,%ecx与第三个参数**(第三个参数只能为1,2,4,8,左移运算符)**相乘并与基址相加,最后赋值给%eax。