我在 AT&T 汇编器语法中为 gcc 编写了以下代码
.global main
.section .data
to_gen_inner: #x f, implicit n
pushl %ebp
movl %esp, %ebp
movl $0xFF00FF00, %eax
call printregs
lret
.set to_gen_inner_len, . - to_gen_inner
.section .text
main:
pushl %ebp
movl %esp, %ebp
#allocate memory
pushl $to_gen_inner_len
call malloc
popl %ecx
pushl $to_gen_inner_len
pushl to_gen_inner
pushl %eax
call copy_bytes
popl %eax
popl %ecx
popl %ecx
lcall *(%eax)
movl %ebp, %esp
popl %ebp
ret
printfregs:
.ascii "eax: %8X\nebx: %8X\necx: %8X\nedx: %8X\n\0"
printregs:
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
pushl $printfregs
call printf
popl %ecx
popl %eax
popl %ebx
popl %ecx
popl %edx
lret
copy_bytes: #dest source length
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %ecx # dest
movl %eax, -4(%ebp)
movl 12(%ebp), %ebx # source
movl %eax, -8(%ebp)
movl 16(%ebp), %eax # length
movl %eax, -12(%ebp)
addl %eax, %ecx # last dest-byte
movl %ecx, -16(%ebp)
addl %eax, %edx # last source-byte
movl %ecx, -20(%ebp)
movl -4(%ebp), %eax
movl -8(%ebp), %ebx
movl -16(%ebp), %ecx
copy_bytes_2:
movb (%ebx), %dl
movb %dl, (%eax)
incl %eax
incl %ebx
cmp %eax, %ecx
jne copy_bytes_2
movl %ebp, %esp
popl %ebp
ret
实际上,我想要做的是将函数代码复制to_gen_inner
到我用malloc分配的内存中,然后跳转到它。此代码产生分段错误。gdb 说:
Program received signal SIGSEGV, Segmentation fault.
main () at speicher3.S:32
32 lcall *(%eax)
Current language: auto; currently asm
(gdb) disas $pc-5 $pc+5
Dump of assembler code from 0x80483eb to 0x80483f5:
0x080483eb <main+23>: add %al,(%eax)
0x080483ed <main+25>: pop %eax
0x080483ee <main+26>: pop %ecx
0x080483ef <main+27>: pop %ecx
0x080483f0 <main+28>: lcall *(%eax)
0x080483f2 <main+30>: mov %ebp,%esp
0x080483f4 <main+32>: pop %ebp
End of assembler dump.
(gdb) disas $pc-6 $pc+5
Dump of assembler code from 0x80483ea to 0x80483f5:
0x080483ea <main+22>: add %al,(%eax)
0x080483ec <main+24>: add %bl,0x59(%eax)
0x080483ef <main+27>: pop %ecx
0x080483f0 <main+28>: lcall *(%eax)
0x080483f2 <main+30>: mov %ebp,%esp
0x080483f4 <main+32>: pop %ebp
End of assembler dump.
(gdb)
我其实不知道为什么。我已经在使用 lcall 和 lret,我读过它被认为是绝对调用,使用 call 和 ret,它也不起作用,同样的错误。
我不知道我做错了什么。有人可以帮我吗?