原本想Qt能继续坚持下来,但是绕了一大圈,最终仍是选择回到学期伊始的Linux汇编编程上来。鉴于图书馆只能借到这本书,虽然不厚,可是内容仍是比较实用丰富,做为入门教程至关不错。之后将不断更新其阅读内容、我的感悟和相关汇编代码。一方面和你们分享,另外一方面,也锻炼我写博文的能力和培养记录的良好习惯。为之后工做作铺垫。至于Qt,我想先推推——C++11正在看,因此仍是但愿有一个比较好的铺垫。基础夯实了,后面的路感受会好走一些。
shell
这里的内存就先不详细说了,能够参考其余资料。
编程
主要说下环境:该书使用32位X86汇编,因此默认一个字=4Bytes数组
一、当即数寻址:指令中包含传输的数字,如 :movl $1, %eax,表示将数“1”存储到寄存器eax中。oop
二、寄存器寻址:指令中给出要访问的寄存器号,如:movl $1, %eax,寻找的为eax寄存器spa
三、直接寻址: 指令中直接给出内存的段内偏移地址。如 movl $1, 2 表示将数“1”存入内存ds:2中code
四、变址寻址:基址用常数表示,偏移量存储在寄存器中。同时能够固定某个整数做为比例因子(步进)。(数组的遍历)教程
五、间接寻址:寄存器中存储要访问的内存偏移量。索引
六、基址寻址:寄存器存储基址,一个常数表示偏移量。(访问结构性数据) ip
#目的:退出程序,向Linux内核返回一个状态码 #输入:无 #输出:想Linux内核返回状态码,程序运行结束后,用shell命令:echo $? 查看返回的状态码 #变量:%eax 系统调用号 %ebx 返回状态吗 .section .data .section .text .globl _start _start: movl $1, %eax #系统调用号 movl $0, %ebx #返回操做码 int 0x80 #中断调用
如上为汇编程序exit.s,编译程序: as exit.s -o exit.o内存
连接程序 : ld exit.o -o exit
运行程序:./exit
查看返回码:echo $?
一、.section .data :“.”表示汇编程序的伪指令,指导编译器的行为。该段为数据段。
二、.section .text:该段为代码段,本段存放须要执行的命令。
三、.globl _start:表示标号_start后面的代码段为全局,其表示为程序的入口。
四、前缀“e”表示32位寄存器,前缀“r”表示64位寄存器,如“rax”
五、通用寄存器有如下几个:%eax, %ebx, %ecx ,%edx, %edi, %esi
专用寄存器有如下几个:%ebp,%esp,%eip,%eflags
六、当进行系统调用时,%eax存系统调用号,%ebx存向系统返回的状态码,int表示中断,此指令将调用终端程序。
#目的:寻找一维数组中最大值 #变量: %edi——当前数组元素的下表(索引) # %ebx——当前最大值 # %eax——当前数据项 #数据段:data_items:0表示数组结束 .section .data data_items: .long 3,67,32,222,45,75,54,33,22,11,66 .section .text .globl _start _start: movl $0, %edi #索引值从0开始 movl data_items(,%edi,4), %eax #使用变址寻址法,给出步进长度为4 movl %eax, %ebx #初始时第一项为最大值 start_loop: cmpl $0, %eax #判断是否到达数组末尾 je loop_exit #到达数组末尾,退出循环,做收尾工做 incl %edi #未到达末尾,索引加1 movl data_items(,%edi,4), %eax cmpl %ebx, %eax #与当前最大值进行比较 jle start_loop # %eax <= %ebx movl %eax, %ebx # %eax > %ebx,则进行交换 jmp start_loop loop_exit: movl $1, %eax # 1为系统调用exit()的调用号 int $0x80 #中断调用
编译:as maximum.s -o maximum.o
连接:ld maximum.o -o maximum
运行:./maximum
查看返回结果:echo $?
一、data_items中的“.long”表示数据类型,汇编语言中有如下数据类型可供使用:
(1).byte:占1 byte, 范围0~255
(2).int :占2 byte,范围:0~65535
(3).long :占4 byte, 范围:0~4 294 967 295
(4).ascii:用于将字符输入内存,每一个字符占一个byte,如:.ascii "hello world\0",“\0”表示字符串末尾
二、对于数组,能够有以下方式表示:
(1)数组长度做为第一个元素
(2)数组末尾用特殊符号标记
三、注意上面的最大值不能超过255,由于程序的退出状态码最大为255。
四、条件跳转指令:当使用条件跳转指令时,须要使用cmpl指令对两个数进行比较:cmpl a , b。条件跳转指令有:
(1)je :当 a==b时,跳转到目标地址
(2)jg:当 b>a时,则跳转。
(3)jge:当 b >= a时,则跳转
(4)jl : 当 b <a 时,则跳转
(5)jle :当 b<=a时,则跳转
(6)jmp:无条件跳转
五、寻址方式:
(1)索引寻址方式:地址或偏移(%基址寄存器,%索引寄存器,比例因子),
结果地址=地址或偏移+%基址或偏移量寄存器+比例因子 * %索引寄存器
须要注意:地址或偏移量、比例因子必须为常数,其他两个必须为寄存器,若省略任何一项可用0代替。地址和偏移量寄存器可省略,但需加后面的“逗号”。
(2)其余寻址方式参考第二章内容
六、关于指令中数据的字长:
(1)movl表示传输一个“字”的数据,若只想传输一个“字节”,则使用指令movb,
(2)%eax的低字节为%ax,%ax的高一字节为%ah,低一字节为%al。