BOMB LAB
lab phase1
bomb.c phase1 code:
bomb.s phase1 code:
401338 对应 string_not_equal函数:
工具介绍
objdump 使用
objdump是一个用于分析可执行文件、目标文件和共享库的工具。它可以显示这些文件的二进制指令、符号表、段信息、重定位表等内容,帮助开发者了解和调试程序。
objdump的常用选项和用法如下:
-
显示二进制指令:
objdump -d <file>
,这会以汇编代码的形式显示可执行文件或目标文件的二进制指令。 -
显示符号表:
objdump -t <file>
,这会显示可执行文件或目标文件的符号表,包括函数名、变量名等信息。 -
显示段信息:
objdump -h <file>
,这会显示可执行文件或目标文件的段信息,包括段名、段地址、段大小等。 -
显示重定位表:
objdump -r <file>
,这会显示可执行文件或目标文件的重定位表,用于动态链接和地址重定位。 -
显示动态符号表:
objdump -T <file>
,这会显示可执行文件或共享库的动态符号表,包括动态链接的函数和变量。 -
反汇编指定函数:
objdump -d <file> -j <section>
,这会反汇编指定节(section)的内容,可以用于分析特定函数的汇编代码。
除了上述常用选项,objdump还提供了许多其他选项,可以根据需要进行使用。可以通过 objdump --help
命令查看完整的选项列表和使用说明。
请注意,objdump是一个命令行工具,可以在Linux、Unix和类似系统中使用。在Windows系统上,可以使用MinGW或Cygwin等工具来使用objdump。
汇编语法
sub 指令
在汇编语言中,SUB(Subtract)指令用于执行两个操作数的减法运算,并将结果存储到目标操作数中。SUB指令有多种形式,可以用于不同的数据类型和寻址方式。
以下是x86汇编语言中SUB指令的一些常见形式:
-
SUB reg, reg/mem:执行两个寄存器或内存位置的减法操作,并将结果存储到第一个操作数中。例如,
SUB EAX, EBX
将EBX的值从EAX中减去,并将结果存储回EAX寄存器。 -
SUB reg, imm:执行寄存器和立即数之间的减法操作,并将结果存储到寄存器中。例如,
SUB EAX, 10
将EAX寄存器的值减去10,并将结果存储回EAX寄存器。 -
SUB mem, reg/imm:执行内存位置和寄存器或立即数之间的减法操作,并将结果存储到内存位置中。例如,
SUB [EBX], ECX
将ECX寄存器的值从EBX指向的内存位置中减去,并将结果存储回该内存位置。
SUB指令的结果影响标志位寄存器(Flags Register),可以通过检查这些标志位来判断减法操作的结果。例如,ZF(Zero Flag)被设置为1表示结果为零,SF(Sign Flag)被设置为1表示结果为负数。
需要注意的是,SUB指令会修改操作数的值,因此在使用之前需要确保操作数的值是正确的,并且结果不会溢出。
mov指令
在汇编语言中,MOV(Move)指令用于将数据从一个位置复制到另一个位置。它是汇编语言中最常用的指令之一,用于数据的加载、存储和传递。
MOV指令有多种形式,可以用于不同的数据类型和寻址方式。以下是x86汇编语言中MOV指令的一些常见形式:
-
MOV reg, reg/mem:将一个寄存器或内存位置的值复制到另一个寄存器中。例如,
MOV EAX, EBX
将EBX寄存器的值复制到EAX寄存器中。 -
MOV reg, imm:将一个立即数(常数)复制到寄存器中。例如,
MOV EAX, 10
将值10复制到EAX寄存器中。 -
MOV mem, reg/imm:将一个寄存器或立即数的值复制到内存位置中。例如,
MOV [EBX], ECX
将ECX寄存器的值复制到EBX指向的内存位置中。
MOV指令可以用于不同的寻址方式,如直接寻址、间接寻址、基址加变址寻址等。它允许在寄存器和内存之间进行数据传输,以及在寄存器之间进行数据交换。
需要注意的是,MOV指令只能将数据从源位置复制到目标位置,而不能进行数学运算。如果需要进行数学运算,需要使用其他指令,如ADD(加法)、SUB(减法)等。
MOV指令的执行速度非常快,因为它是在寄存器之间直接进行数据传输,而不涉及内存访问。因此,在性能要求较高的场景中,使用MOV指令可以提高程序的执行效率。
movq 指令
movq指令:
movq 参数
movq 参数介绍
地址格式:
call 指令
callq 指令
callq 指令例子:
leaq 指令
cmpq 指令
testq 指令
pushq 指令
popq 指令
关于指令的思考
call 和 callq的区别
在汇编语言中,CALL和CALLQ是两种不同的指令,它们在不同的体系结构中使用。
- CALL指令:
CALL指令是在x86体系结构中使用的指令。它用于调用(跳转到)一个子程序或函数。CALL指令的操作数可以是一个标签、一个寄存器或一个内存地址。
当执行CALL指令时,会将当前指令的下一条指令的地址(即CALL指令的下一条指令)压入栈中,然后跳转到操作数所指定的子程序或函数的起始地址。
- CALLQ指令:
CALLQ指令是在x86-64体系结构中使用的指令。它与CALL指令的功能相同,都是用于调用(跳转到)一个子程序或函数。但是,CALLQ指令是64位模式下的指令,用于支持更大的地址空间。
CALLQ指令的操作数可以是一个标签、一个寄存器或一个内存地址。它与CALL指令的区别在于,CALLQ指令使用64位的地址寻址方式,可以访问更大的内存空间。
总结:
CALL指令是在32位x86体系结构中使用的指令,而CALLQ指令是在64位x86-64体系结构中使用的指令。它们的功能相同,都用于调用(跳转到)一个子程序或函数,但是CALLQ指令适用于64位模式下的更大地址空间。
leaq和movq的区别
leaq
指令和movq
指令是x86汇编语言中常用的指令,用于处理数据的加载和传输。它们的区别如下:
-
功能:
leaq
指令用于将一个内存地址或偏移量加载到寄存器中,而不是将内存中的值加载到寄存器。它主要用于计算地址,而不是数据传输。movq
指令用于将一个值从一个位置(寄存器、内存或立即数)复制到另一个位置(寄存器或内存)。
-
语法:
leaq
指令的语法为leaq <源操作数>, <目的操作数>
,其中源操作数是一个内存地址或偏移量,目的操作数是一个寄存器。movq
指令的语法为movq <源操作数>, <目的操作数>
,其中源操作数和目的操作数可以是寄存器、内存位置或立即数。
-
执行时间:
leaq
指令通常比movq
指令更快,因为它只执行地址计算,而不涉及内存读取或写入操作。
-
使用场景:
leaq
指令常用于计算数组元素的地址、计算偏移量、进行指针运算等需要计算地址的场景。movq
指令常用于数据传输、寄存器之间的值交换、常量加载等数据操作场景。
总之,leaq
指令用于计算地址,而movq
指令用于数据传输和复制。它们在功能、语法和使用场景上有明显的区别。
寄存器知识点
寄存器
x86 寄存器:
寄存器功能:
condition code:
memory 地址
地址模型
参考链接
https://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/lectures/05-machine-basics.pdf
https://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/lectures/06-machine-control.pdf
https://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/lectures/07-machine-procedures.pdf