汇编函数
- 定义函数
- 定义输入
- 使用寄存器传值
- 使用全局变量传值
- 使用栈传值
- 定义函数
- 语法
- 定义输入
.type func1, @funcion
func1:
...
ret
- 定义输出
- 将输出放在一个或几个寄存器
- 将输出放在一个全局变量
- 创建函数
- 计算圆形面积的示例
.type area, @function
area:
fldpi
imull %ebx, %ebx
movl %ebx, value
filds value
fmulp %st(0), %st(1)
ret
-
说明
- 输入值必须以整形值的方式存放在EBX
- 一个4字节的内存必须在主程序中被创建
- 输出存放在ST(0)
-
访问函数
- 语法
call function - 示例
- 语法
# functest.s - An example of using functions
.section .data
precision:
.byte 0x7f, 0x00
.section .bss
.lcomm value, 4
.section .text
.globl _start
_start:
nop
finit
fldcw precison
movl $10, %ebx
call area
movl $2, %ebx
call area
movl $120, %ebx
call area
movl $1, %eax
movl $0, %ebx
int $0x80
.type area, @function
area:
fldpi
imull %ebx, %ebx
movl %ebx, value
filds value
fmulp %st(0), %st(1)
ret
- 使用全局变量
- 示例
# functest.s - An example of using global variables in functions
.section .data
precision:
.byte 0x7f, 0x00
.section .bss
.lcomm radius, 4
.lcomm result, 4
.lcomm trash, 4
.section .text
.globl _start
_start:
nop
finit
fldcw precision
movl $10, radius
call area
movl $2, radius
call area
movl $120, radius
call area
movl $1, %eax
movl $0, %ebx
int $0x80
.type area, @function
area:
fldpi
filds radius
fmul %st(0), %st(0)
fmulp %st(0), %st(1)
fstps result
ret
用c的风格传值
- 通过栈传递方法参数
- 将参数和返回值压栈
- 参数压栈顺序与函数参数顺序相反
- 为获得参数通过ebp的相对地址获得
- 进入方法前就esp存入ebp
- 函数标准格式
function:
pushl %ebp
movl %esp, %ebp
.
.
movl %ebp, %esp
popl %ebp
ret
-
定义局部变量数据
- esp减去一个默认的大小,为局部变量预留空间
-
平衡栈
pushl %eax
pushl %ebx
call compute
addl $8, %esp
* 示例
# functest.s - An example of using C style functions
.section .data
precision:
.byte 0x7f, 0x00
.section .bss
.lcomm result, 4
.section .text
.globl _start
_start:
nop
finit
fldcw precision
pushl $10
call area
addl $4, %esp
movl %eax, result
pushl $2
call area
addl $4, %esp
movl %eax, result
pushl $120
call area
addl $4, %esp
movl %eax, result
movl $1, %eax
movl $0, %ebx
int $0x80
.type area, @function
area:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
fldpi
filds 8(%ebp)
fmul %st(0), %st(0)
fmulp %st(0), %st(1)
fstps -4(%ebp)
movl -4(%ebp), %eax
movl %ebp, %esp
pop %ebp
ret
使用独立的文件方法
- 创建一个独立的方法文件
- 语法
# area.s - The area function
.section .text
.type area, @function
.globl area
area:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
fldpi
filds 8(%ebp)
fmul %st(0), %st(0)
fmulp %st(0), %st(1)
fstps -4(%ebp)
movl -4(%ebp), %eax
movl %ebp, %esp
popl %ebp
ret
- 使用文件
# functest.s - An example of using C style functions
.section .data
precision:
.byte 0x7f, 0x00
.section .bss
.lcomm result, 4
.section .text
.globl _start
_start:
nop
finit
fldcw precision
pushl $10
call area
addl $4, %esp
movl %eax, result
pushl $2
call area
addl $4, %esp
movl %eax, result
pushl $120
call area
addl $4, %esp
movl %eax, result
movl $1, %eax
movl $0, %ebx
int $0x80
- 生成可执行文件
- as -gstabs -o area.o area.s
- as -gstabs -o functest.o functest.s
- ld -o functest functest.o area.o
使用命令行参数
-
程序骨架
- 程序段
- 堆栈段
- 程序启动时堆栈段存放的数据
- 命令行的参数个数
- 程序的名称
- 命令行的具体参数
- 当前的环境变量
- 程序启动时堆栈段存放的数据
-
打印命令行参数
# paramtest.s - Listing command line parameters
.section .data
output1:
.asciz "There are %d parameters:\n"
output2:
.asciz "%s\n"
.section .text
.globl _start
_start:
movl (%esp), %ecx
pushl %ecx
pushl $output1
call printf
addl $4, %esp
popl %ecx
movl %esp, %ebp
addl $4, %ebp
loop1:
pushl %ecx
pushl (%ebp)
pushl $output2
call printf
add $8, %esp
popl %ecx
addl $4, %ebp
loop loop1
pushl $0
call exit
- 打印环境变量
# paramtest.s - Listing system environment variables
.section .data
output:
.asciz "%s\n"
.section .text
.globl _start
_start:
movl %esp, %ebp
addl $12, %ebp
loop1:
cmpl $0, (%ebp)
je endit
pushl (%ebp)
pushl $output
call printf
addl $12, %esp
add $4, %ebp
loop loop1
endit:
pushl $0
call exit
- 使用命令行参数示例
# paramtest.s - An example of using command line parameters
.section .data
output:
.asciz "The area is: %f\n"
.section .bss
.lcomm result, 4
.section .text
.globl _start
_start:
nop
finit
pushl 8(%esp)
call atoi
addl $4, %esp
movl %eax, result
fldpi
filds resutl
fmul %st(0), %st(0)
fmul %st(1), %st(0)
fstpl (%esp)
pushl $output
call printf
addl $12, %esp
pushl $0
call exit