汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。——百度百科
人话:机器语言的plus版,人能看但是麻烦。
关于.c(c语言产生的文件)如何变成系统可执行的程序:
预处理器:处理c语言的头文件,得到的仍然是C程序,但是以.i为文件扩展名。
编译器:C语言转汇编语言,以.s为扩展名。
汇编器:处理汇编语言变成机器语言指令,生成一种“可重定位目标程序”,内容保存在.o文件中。
链接器:整合标准C库的函数,一起打包到.o文件中,得到“可执行目标文件”。
因为汇编语言是在寄存器和内存中来回蹦迪的,了解寄存器也是必须滴。
不同位的系统寄存器也不同,可以概括为下图的情况:
二图来源:@湖南大学计算机系统课程组(侵删)
64位的寄存器有rax,rbx,rcx……,并且支持向下兼容,即64位的寄存器兼容32位。
拿图的第一行举例:rax的后32位为eax,eax的后16位为ax,ax的前八位为ah,后八位为al。以此类推。
AT&T汇编代码:
来源:@湖南大学计算机系统课程组(侵删)
$8就是一个立即数,eax是寄存器。
了解完毕,实操环节:
软件:VMware,Ubuntu虚拟机
已准备好.s文件,看看内容(cat命令):
有一个int型400和int型数组。
利用as(-g:调试,-o:命名)命令生成.i文件:
利用ld生成(-o同上)可执行文件:
利用gdb(-q:不打印杂七杂八的内容)调试:
如同写C语言代码调试一样,我们可以设置断点来查看我们感兴趣的内容:
在_start的下一句nop设置一个断点:
输入r开始跑,n为执行下一条指令。
每条语句和.s文件顺序都对的上(注意:每次输入n之后在shell上显示的是下一条将要执行的语句)
在这个程序中,有几点值得留意:
movl,movw,movb有啥区别。
movl:传送32位长字值
movw(word):传送16位字值
movb(byte):传送8位字值
#############################################################################
对于如下文件
对于第八行的命令,用movb传入一个ff65的立即数,dh最终会保存为多少?
用“i r(info reg)” 查看:
dh中只保存了65。
为啥?
ff65转二进制为111111111111 01100101,只有低八位传入dh中。
以上指令若改为:movl $1,%al 就会报错,因为movl是32位,而al只有8位。
#############################################################################
这是啥玩意?
比例变址基址寻址:
地址表达式:D(Rb,Ri,s)
有效地址:EA=D+(Rb+Ri*s),s只能是1,2,4,8(移位操作,速度快)
对这里而言,eax的值是values地址+edi寄存器存的数字+ebx存的数字*1得到的地址中的数
用objdump反汇编可以得到地址,机器码,汇编。
EA=0x402004+2+4*1=0x40200a
利用x/4bx 查看内存内容:
用“i r”查看:
二者一致。
lea指令和mov指令的区别:
来源:@湖南大学计算机系统课程组(侵删)
人话:写的是地址
将movl改成lea后再用“i r”
结果与上文推断一样。