一、不同
1.系统调用号不同。比如x86中sys_write是4,sys_exit是1;而x86_64中sys_write是1, sys_exit是60。linux系统调用号实际上定义在/usr/include/asm/unistd_32.h和/usr/include/asm/unistd_64.h中。
2.系统调用所使用的寄存器不同,x86_64中使用与eax对应的rax传递系统调用号,但是 x86_64中分别使用rdi/rsi/rdx传递前三个参数,而不是x86中的ebx/ecx/edx。
3.系统调用使用“syscall”而不是“int 80”
例子:
32位:
global _start64位:
_start:
jmp short ender
starter:
xor eax, eax ;clean up the registers
xor ebx, ebx
xor edx, edx
xor ecx, ecx
mov al, 4 ;syscall write
mov bl, 1 ;stdout is 1
pop ecx ;get the address of the string from the stack
mov dl, 5 ;length of the string
int 0x80
xor eax, eax
mov al, 1 ;exit the shellcode
xor ebx,ebx
int 0x80
ender:
call starter ;put the address of the string on the stack
db 'hello',0x0a
global _start ; global entry point export for ld_start: jump short string ; get message addrcode: ; sys_write(stdout, message, length) pop rsi ; message address mov rax, 1 ; sys_write mov rdi, 1 ; stdout mov rdx, 13 ; message string length + 0x0a syscall ; sys_exit(return_code) mov rax, 60 ; sys_exit mov rdi, 0 ; return 0 (success) syscallstring: call code db 'Hello!',0x0a ; message and newline二、兼容
由于硬件指令的兼容,32位的程序在用户态不受任何影响的运行,由于内核保留了0x80号中断作为32位程序
的系统调用服务,因此32位程序可以安全触发0x80号中断使用系统调用,由于内核为0x80中断安排了另一
套全新的系统调用表,因此可以安全地转换数据类型成一致的64位类型,再加上应用级别提供了两套c库,
可以使64位和32位程序链接不同的库