记住x86-64 System V arg寄存器顺序的最佳方法是什么? [英] What's the best way to remember the x86-64 System V arg register order?

查看:79
本文介绍了记住x86-64 System V arg寄存器顺序的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常忘记在系统调用中需要用于每个参数的寄存器,每次我忘记访问解决方案

如果您还记得C memcpy 的arg顺序,以及


实际的设计过程包括最小化在使用当时最新的GCC AMD64端口进行编译时(也许是SPECcpu)的指令数量和代码大小之间的成本权衡.我不知道作为 rep movsb inline memcpy是否相关,或者当时的glibc是否实际上以这种方式实现了它,或者是什么.

我在 Linux x64:为什么在系统调用中,r10排在r8和r9之前?

  • 为什么RCX是否不用于将参数传递给系统调用而被R10取代?

  • 替代:助记符:

    D iane的 s ilk d ress c osts $ 89

    (建议由 CS:APP博客)

    I often forget the registers that I need to use for each argument in a syscall, and everytime I forget I just visit this question.

    The right order for integer/pointer args to x86_64 user-space function calls is:
    %rdi, %rsi, %rdx, %rcx, %r8 and %r9. (with variadic functions taking AL = the number of FP args, up to 8)

    Or for system calls, %rax (syscall call number), and same args except %r10 instead of %rcx.

    What's the best way to remember these registers instead of google this question every time?

    解决方案

    If you remember C memcpy's arg order, and how rep movsb works, that's most of the way to remembering x86-64 System V.

    The design makes memcpy(dst, src, size) cheap to implement with rep movsb, except leaving RCX unused in more functions because it's needed for variable-count shifts more often than anything needs RDX.

    Then R8 and R9 are the first two "high" registers. Using them requires a REX prefix, which costs an extra byte of code size in instructions that wouldn't otherwise need one. Thus they're a sensible choice for the last 2 args. (Windows x64 makes the same choice of using R8, R9 for the last 2 register args).


    The actual design process involved minimizing a cost tradeoff of instruction count and code-size for compiling something (perhaps SPECcpu) with a then-current AMD64 port of GCC. I don't know whether inlining memcpy as rep movsb was relevant, or whether glibc at the time actually implemented it that way, or what.

    My answer on Why does Windows64 use a different calling convention from all other OSes on x86-64? cites some sources for the calling convention design decisions. (Early x86-64.org mailing list posts from GCC devs, notably Jan Hubicka who experimented with a few register orders before coming up with this one.)

    Of particular note for remembering the RDX, RCX part of the order is this quote:

    We are trying to avoid RCX early in the sequence, since it is register used commonly for special purposes, like EAX, so it has same purpose to be missing in the sequence. Also it can't be used for syscalls and we would like to make syscall sequence to match function call sequence as much as possible.


    User-space vs. syscall difference:

    R10 replaces RCX in the system call convention because the syscall instruction itself destroys RCX (using it to save RIP, avoiding using the user-space stack, and it can't use the kernel stack because it leaves stack switching up to software). Like how it uses R11 to save RFLAGS.

    Keeping it as similar as possible allows libc wrappers to just mov %rcx, %r10, not shuffle over multiple args to fill the gap. R10 is the next available register after R8 and R9.


    Alternative: a mnemonic:

    Diane's silk dress costs $89

    (Suggested by the CS:APP blog)

    这篇关于记住x86-64 System V arg寄存器顺序的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆