相关疑难解决方法(0)

132
推荐指数
4
解决办法
10万
查看次数

如果在64位代码中使用32位int 0x80 Linux ABI会发生什么?

int 0x80在Linux上总是调用32位ABI,不管是什么模式,这就是所谓的:在args ebx,ecx...和系统调用号的/usr/include/asm/unistd_32.h.(或者在没有编译的64位内核上崩溃CONFIG_IA32_EMULATION).

64位代码应该使用syscall,从呼叫号码/usr/include/asm/unistd_64.h,并在args rdi,rsi等见什么调用约定UNIX和Linux系统上的i386和x86-64调用.如果您的问题被打上这样一个重复的,看你怎么说链接,细节应当使32位或64位代码的系统调用. 如果你想了解到底发生了什么,请继续阅读.


sys_write系统调用比syscall系统调用快,所以使用本机64位,int 0x80除非你正在编写多格式机器代码,当执行32或64位时运行相同的机器代码.(syscall始终以32位模式返回,因此它在64位用户空间中没有用,尽管它是有效的x86-64指令.)

相关:Linux系统的权威指南(在x86上)调用如何进行sysenterint 0x8032位系统调用,或sysenter64位系统调用,或调用vDSO进行"虚拟"系统调用syscall.加上有关系统调用的背景知识.


使用gettimeofday可以编写将以32位或64位模式组合的内容,因此它可以int 0x80在微基准测试结束时使用.

标准化函数和系统调用约定的官方i386和x86-64 System V psABI文档的当前PDF文件链接自https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI.

有关初学者指南,x86手册,官方文档和性能优化指南/资源,请参阅标记wiki.


但是,由于人们不断发布与使用代码的问题exit_group()在64位代码,或不小心建立64位二进制文件从源代码对于32位写的,我不知道是什么确切不会对当前的Linux怎样呢?

是否int 0x80保存/恢复所有的64位寄存器?它会将任何寄存器截断为32位吗?如果传递上半部分非零的指针args会发生什么?

如果你传递32位指针它是否有效?

linux assembly x86-64 system-calls abi

36
推荐指数
1
解决办法
4783
查看次数

ptrace 能否判断 x86 系统调用使用的是 64 位还是 32 位 ABI?

我正在尝试使用 ptrace 来跟踪由单独进程发出的所有系统调用,无论是 32 位 (IA-32) 还是 64 位 (x86-64)。我的跟踪器将在启用 IA-32 仿真的 64 位 x86 安装上运行,但理想情况下能够跟踪 64 位和 32 位应用程序,包括 64 位应用程序是否分叉并执行 32 位进程.

问题是,由于 32 位和 64 位系统调用号不同,我需要知道进程是 32 位还是 64 位以确定它使用哪个系统调用,即使我有系统调用号。似乎有不完美的方法,例如检查/proc/<pid>/exec或(如 strace 那样)寄存器结构的大小,但没有什么可靠的。

更复杂的是,64 位进程可以从长模式切换到直接执行 32 位代码。他们还可以进行 32 位int $0x80系统调用,当然,使用 32 位系统调用号。我不“相信”我跟踪的进程不会使用这些技巧,所以我想正确检测它们。而且我已经独立验证,至少在后一种情况下,ptrace 看到的是 32 位系统调用号和参数寄存器分配,而不是 64 位的。

我在内核源代码中找到了 中的TS_COMPAT标志arch/x86/include/asm/processor.h,每当 64 位进程进行 32 位系统调用时,该标志似乎都会设置。唯一的问题是我不知道如何从用户空间访问这个标志,或者是否有可能。

我还考虑过阅读%cs并将其与$0x23or进行比较$0x33,受到这种在运行过程中切换位数的 …

linux x86 ptrace x86-64 system-calls

7
推荐指数
1
解决办法
845
查看次数

在装配中使用 printf 会导致管道输出为空,但在终端上有效

我尝试printf从我的汇编代码中使用,这是一个应该打印hello到标准输出的最小示例:

.section  .rodata
hello:
    .ascii  "hello\n\0"
.section .text
    .globl _start        
_start:
    movq $hello, %rdi     # first parameter
    xorl %eax, %eax       # 0 - number of used vector registers
    call printf        
#exit   
    movq $60, %rax
    movq $0, %rdi
    syscall
Run Code Online (Sandbox Code Playgroud)

我用

gcc -nostdlib try_printf.s -o try_printf -lc
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它似乎工作:字符串hello被打印出来,退出状态是0

XXX$ ./try_printf
hello
XXX$ echo $?
0
XXX$
Run Code Online (Sandbox Code Playgroud)

但是当我尝试捕获文本时,很明显,某些内容无法正常工作:

XXX$ output=$(./try_printf) 
XXX$ echo $output

XXX$ 
Run Code Online (Sandbox Code Playgroud)

该变量output应具有 value hello,但为空。

我的用法有printf什么问题?

linux assembly printf glibc x86-64

4
推荐指数
1
解决办法
1359
查看次数

标签 统计

linux ×4

x86-64 ×4

assembly ×3

abi ×2

system-calls ×2

glibc ×1

printf ×1

ptrace ×1

unix ×1

x86 ×1