|
1:
在64位机器上压栈的时候一定要把整个寄存器的值压入,不能够只压入其中的32位?
我正在看的汇编是32位的,然后32位的代码在64位的机器上居然用汇编器通不过。我印象中应该是向下兼容的啊,就像32位的兼容16位的一样,当只需要16位的时候就只要使用寄存器ax,要32位的时候才eax。push指令应该可以把任何值压入堆栈的吧,在64位的机器上压栈的时候却一定要把整个寄存器的值压入,不能够只压入其中的32位(pushl %eax报错,一定要pushq %rax才行)。这是怎么回事?
2:
不同的系统调用值却能够正常工作?
书上说Linux的系统调用及其编号在/usr/include/asm/unistd.h中包含了。于是我在64位系统上打开了这个文件,却看到几行宏定义。
unistd.h:
# ifdef __i386__
# include "unistd_32.h"
# else
# include "unistd_64.h"
# endif
于是我打开了unistd_32.h。
unistd_32.h(一部分):
#ifndef _ASM_X86_UNISTD_32_H
#define _ASM_X86_UNISTD_32_H
/*
* This file contains the system call numbers.
*/
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
这个跟书上说的一样,exit的系统调用是1。
之后我打开了unistd_64.h。
unistd_64.h(一部分):
#ifndef _ASM_X86_UNISTD_64_H
#define _ASM_X86_UNISTD_64_H
#ifndef __SYSCALL
#define __SYSCALL(a, b)
#endif
/*
* This file contains the system call numbers.
*
* Note: holes are not allowed.
*/
/* at least 8 syscall per cacheline */
#define __NR_read 0
__SYSCALL(__NR_read, sys_read)
#define __NR_write 1
__SYSCALL(__NR_write, sys_write)
#define __NR_open 2
__SYSCALL(__NR_open, sys_open)
#define __NR_close 3
__SYSCALL(__NR_close, sys_close)
#define __NR_stat 4
__SYSCALL(__NR_stat, sys_newstat)
#define __NR_fstat 5
__SYSCALL(__NR_fstat, sys_newfstat)
#define __NR_lstat 6
这看起来在64位系统上系统调用exit的编号不是1。
但是我用包含下面的指令的32位汇编程序在32位机器上汇编并链接出来的程序在64位机器上却能够正常运行?
functest3.s(结尾部分):
movl $1 %eax
movl $0 %ebx
int 0x80
gdb调试信息(64位机器上):
lucifer@cross:~/Desktop/test$ gdb -q ./functest3_32
Reading symbols from /home/lucifer/Desktop/test/functest3_32...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/lucifer/Desktop/test/functest3_32
Program exited normally.
(gdb) q
lucifer@cross:~/Desktop/test$
3:
同样的C代码为什么在64位的机器上汇编出来的汇编程序的行数比在32位机器上汇编出来的程序的行数要多?要运行的指令多了速度还能更快?多出来的代码是在干什么?
tmp3.c:
#include <stdio.h>
int add(int a,int b);
int
main()
{
int ret = add(2,3);
return 0;
}
int
add(int a,int b)
{
int i = 4;
return a+b+i;
}
32位机器上汇编出来的程序源码:
tmp3_32.s(共33行):
.file "tmp3.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $3, 4(%esp)
movl $2, (%esp)
call add
movl %eax, 28(%esp)
movl $0, %eax
leave
ret
.size main, .-main
.globl add
.type add, @function
add:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $4, -4(%ebp)
movl 12(%ebp), %eax
movl 8(%ebp), %edx
leal (%edx,%eax), %eax
addl -4(%ebp), %eax
leave
ret
.size add, .-add
.ident "GCC: 4.4.3"
.section .note.GNU-stack,"",@progbits
64位机器上汇编出来的程序源码:
tmp3_64.s(共47行):
.file "tmp3.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq $16, %rsp
movl $3, %esi
movl $2, %edi
call add
movl %eax, -4(%rbp)
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.globl add
.type add, @function
add:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl $4, -4(%rbp)
movl -24(%rbp), %eax
movl -20(%rbp), %edx
leal (%rdx,%rax), %eax
addl -4(%rbp), %eax
leave
ret
.cfi_endproc
.LFE1:
.size add, .-add
.ident "GCC: 4.4.3"
.section .note.GNU-stack,"",@progbits |
|