汇编语言程序设计-学习
第6章:控制执行流程
目录:
无条件分支:
<1>.跳转
短跳:128byte之内
长跳:分段内存模式,跳转到另一个段
近跳:其他
<2>.调用
<3>.中断
条件分支:(EFLAGS-register)
carry--进位(CF):0bit,主要用于无符号数小于0,或是大于数字范围。
overflow--溢出(OF):11bit,主要用于有符号位,超出范围。
parity--奇偶校验(PF):2bit
sign--符号(SF):7bit
zero--零(ZF):6bit
******************************************************
一.无条跳转:
1.跳转:
------------------------------------------------------
<1>//编辑汇编源文件
root@ubuntu-core:/home/asm/6_1# cat test.s
# jump test.s -An example of the jmp instruction.
.section .text
.globl _start
_start:
nop
movl $1 ,%eax
jmp overhere
movl $10,%ebx
int $0x80
overhere:
movl $20,%ebx
int $0x80
------------------------------------------------------
<2>.//编译、链接、运行
root@ubuntu-core:/home/asm/6_1#
root@ubuntu-core:/home/asm/6_1# as -o test.o test.s
root@ubuntu-core:/home/asm/6_1# ld -o test test.o
root@ubuntu-core:/home/asm/6_1# ./test
root@ubuntu-core:/home/asm/6_1# echo $?
20
root@ubuntu-core:/home/asm/6_1#
------------------------------------------------------
<3>.//使用可执行文件,反汇编,监视程序中实际使用的内存位置
root@ubuntu-core:/home/asm/6_1# objdump -D test
test: file format elf64-x86-64 //我的系统时64位的.
Disassembly of section .text:
0000000000400078 <_start>:
400078: 90 nop
400079: b8 01 00 00 00 mov $0x1,%eax
40007e: eb 07 jmp 400087 <overhere>
400080: bb 0a 00 00 00 mov $0xa,%ebx
400085: cd 80 int $0x80
0000000000400087 <overhere>:
400087: bb 14 00 00 00 mov $0x14,%ebx
40008c: cd 80 int $0x80
root@ubuntu-core:/home/asm/6_1#
------------------------------------------------------
<4>.//gdb单步调试,查看程序执行流程
root@ubuntu-core:/home/asm/6_1# as -gstabs -o test.o test.s //-gstabs
调试参数:调试器对代码进行汇编
root@ubuntu-core:/home/asm/6_1# ld -o test test.o
root@ubuntu-core:/home/asm/6_1# gdb -q test //-q 去除一些开始信息
Reading symbols from /home/asm/6_1/test...done.
(gdb) break *_start+1 //设置断点
Breakpoint 1 at 0x400079: file test.s, line 10.
(gdb) run //开始运行
Starting program: /home/asm/6_1/test
warning: no loadable sections found in added symbol-file system-supplied DSO
at 0x7ffff7ffd000
Breakpoint 1, _start () at test.s:10
10 movl $1 ,%eax
(gdb) info register //查看程序运行中,各个寄存器的值
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffe010 0x7fffffffe010
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x200 512
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x400079 0x400079 <_start+1>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) print/x $rip //十六进制打印单个寄存器
$1 = 0x400079
(gdb) s //step,单步运行
11 jmp overhere
(gdb) s
overhere () at test.s:15
15 movl $20,%ebx
(gdb) print/x $rip
$2 = 0x400087
(gdb) s
16 int $0x80
(gdb) print/x $rip
$3 = 0x40008c
(gdb) s
[Inferior 1 (process 50888) exited with code 024]
(gdb)
++++++++++++++++++++++++++++++++++++++++++++++++++++++
2.调用:
root@ubuntu-core:/home/asm/6_1# cat calltest.s
#calltest.s -An example of using the CALL instruction
#.code32 //64位汇编与32位汇编不大一样,限定为32位汇编
.section .data
output:
.asciz "This is section %d\n"
.section .text
.globl main
main:
pushl $1
pushl $output
call printf
add $8,%esp
call overhere
pushl $3
pushl $output
call printf
add $8,%esp
pushl $0
call exit
overhere:
pushl %ebp
movl %esp,%ebp
pushl $2
pushl $output
call printf
add $8,%esp
movl %ebp,%esp
popl %ebp
ret
root@ubuntu-core:/home/asm/6_1# gcc -m32 calltest.s -o test //由于我的机子是
X64的
root@ubuntu-core:/home/asm/6_1# ./test
This is section 1
This is section 2
This is section 3
root@ubuntu-core:/home/asm/6_1#
++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.中断
软中断:linux中系统调用也是软件中断
硬中断:硬件产生。
linux:0x80
======================================================
二.条件跳转
使用奇偶校验标志为例:
root@ubuntu-core:/home/asm/6_1# cat paritytest.s
#paritytest.s -An example of testing the parity flag
.section .text
.globl _start
_start:
movl $1,%eax
movl $4,%ebx
subl $3,%ebx
jp overhere
int $0x80
overhere:
movl $100,%ebx
int $0x80
root@ubuntu-core:/home/asm/6_1# as paritytest.s -o test.o
root@ubuntu-core:/home/asm/6_1# ld test.o -o test
root@ubuntu-core:/home/asm/6_1# ./test
root@ubuntu-core:/home/asm/6_1# echo $?
1
root@ubuntu-core:/home/asm/6_1# vim paritytest.s
root@ubuntu-core:/home/asm/6_1# as paritytest.s -o test.o
root@ubuntu-core:/home/asm/6_1# ld test.o -o test
root@ubuntu-core:/home/asm/6_1# ./test
root@ubuntu-core:/home/asm/6_1# echo $?
100
root@ubuntu-core:/home/asm/6_1#
第6章:控制执行流程
目录:
无条件分支:
<1>.跳转
短跳:128byte之内
长跳:分段内存模式,跳转到另一个段
近跳:其他
<2>.调用
<3>.中断
条件分支:(EFLAGS-register)
carry--进位(CF):0bit,主要用于无符号数小于0,或是大于数字范围。
overflow--溢出(OF):11bit,主要用于有符号位,超出范围。
parity--奇偶校验(PF):2bit
sign--符号(SF):7bit
zero--零(ZF):6bit
******************************************************
一.无条跳转:
1.跳转:
------------------------------------------------------
<1>//编辑汇编源文件
root@ubuntu-core:/home/asm/6_1# cat test.s
# jump test.s -An example of the jmp instruction.
.section .text
.globl _start
_start:
nop
movl $1 ,%eax
jmp overhere
movl $10,%ebx
int $0x80
overhere:
movl $20,%ebx
int $0x80
------------------------------------------------------
<2>.//编译、链接、运行
root@ubuntu-core:/home/asm/6_1#
root@ubuntu-core:/home/asm/6_1# as -o test.o test.s
root@ubuntu-core:/home/asm/6_1# ld -o test test.o
root@ubuntu-core:/home/asm/6_1# ./test
root@ubuntu-core:/home/asm/6_1# echo $?
20
root@ubuntu-core:/home/asm/6_1#
------------------------------------------------------
<3>.//使用可执行文件,反汇编,监视程序中实际使用的内存位置
root@ubuntu-core:/home/asm/6_1# objdump -D test
test: file format elf64-x86-64 //我的系统时64位的.
Disassembly of section .text:
0000000000400078 <_start>:
400078: 90 nop
400079: b8 01 00 00 00 mov $0x1,%eax
40007e: eb 07 jmp 400087 <overhere>
400080: bb 0a 00 00 00 mov $0xa,%ebx
400085: cd 80 int $0x80
0000000000400087 <overhere>:
400087: bb 14 00 00 00 mov $0x14,%ebx
40008c: cd 80 int $0x80
root@ubuntu-core:/home/asm/6_1#
------------------------------------------------------
<4>.//gdb单步调试,查看程序执行流程
root@ubuntu-core:/home/asm/6_1# as -gstabs -o test.o test.s //-gstabs
调试参数:调试器对代码进行汇编
root@ubuntu-core:/home/asm/6_1# ld -o test test.o
root@ubuntu-core:/home/asm/6_1# gdb -q test //-q 去除一些开始信息
Reading symbols from /home/asm/6_1/test...done.
(gdb) break *_start+1 //设置断点
Breakpoint 1 at 0x400079: file test.s, line 10.
(gdb) run //开始运行
Starting program: /home/asm/6_1/test
warning: no loadable sections found in added symbol-file system-supplied DSO
at 0x7ffff7ffd000
Breakpoint 1, _start () at test.s:10
10 movl $1 ,%eax
(gdb) info register //查看程序运行中,各个寄存器的值
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffe010 0x7fffffffe010
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x200 512
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x400079 0x400079 <_start+1>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) print/x $rip //十六进制打印单个寄存器
$1 = 0x400079
(gdb) s //step,单步运行
11 jmp overhere
(gdb) s
overhere () at test.s:15
15 movl $20,%ebx
(gdb) print/x $rip
$2 = 0x400087
(gdb) s
16 int $0x80
(gdb) print/x $rip
$3 = 0x40008c
(gdb) s
[Inferior 1 (process 50888) exited with code 024]
(gdb)
++++++++++++++++++++++++++++++++++++++++++++++++++++++
2.调用:
root@ubuntu-core:/home/asm/6_1# cat calltest.s
#calltest.s -An example of using the CALL instruction
#.code32 //64位汇编与32位汇编不大一样,限定为32位汇编
.section .data
output:
.asciz "This is section %d\n"
.section .text
.globl main
main:
pushl $1
pushl $output
call printf
add $8,%esp
call overhere
pushl $3
pushl $output
call printf
add $8,%esp
pushl $0
call exit
overhere:
pushl %ebp
movl %esp,%ebp
pushl $2
pushl $output
call printf
add $8,%esp
movl %ebp,%esp
popl %ebp
ret
root@ubuntu-core:/home/asm/6_1# gcc -m32 calltest.s -o test //由于我的机子是
X64的
root@ubuntu-core:/home/asm/6_1# ./test
This is section 1
This is section 2
This is section 3
root@ubuntu-core:/home/asm/6_1#
++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.中断
软中断:linux中系统调用也是软件中断
硬中断:硬件产生。
linux:0x80
======================================================
二.条件跳转
使用奇偶校验标志为例:
root@ubuntu-core:/home/asm/6_1# cat paritytest.s
#paritytest.s -An example of testing the parity flag
.section .text
.globl _start
_start:
movl $1,%eax
movl $4,%ebx
subl $3,%ebx
jp overhere
int $0x80
overhere:
movl $100,%ebx
int $0x80
root@ubuntu-core:/home/asm/6_1# as paritytest.s -o test.o
root@ubuntu-core:/home/asm/6_1# ld test.o -o test
root@ubuntu-core:/home/asm/6_1# ./test
root@ubuntu-core:/home/asm/6_1# echo $?
1
root@ubuntu-core:/home/asm/6_1# vim paritytest.s
root@ubuntu-core:/home/asm/6_1# as paritytest.s -o test.o
root@ubuntu-core:/home/asm/6_1# ld test.o -o test
root@ubuntu-core:/home/asm/6_1# ./test
root@ubuntu-core:/home/asm/6_1# echo $?
100
root@ubuntu-core:/home/asm/6_1#