V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
thekll
V2EX  ›  程序员

x86-64 汇编的%rip 是不是不再特指指令指针寄存器,可以作为普通整数寄存器使用?

  •  
  •   thekll · 2016-12-25 14:23:21 +08:00 via iPhone · 11667 次点击
    这是一个创建于 2891 天前的主题,其中的信息可能已经有所发展或是发生改变。
    CSAPP 中"程序机器级表示"一章有一段例程:
    long lt_cnt = 0;
    long ge_cnt =0;
    long adsdiff_se(long x,long y)
    {
    long result;
    if(x<y){
    lt_cnt++;
    result = y-x;
    }
    else {
    ge_cnt++;
    result = x-y;
    }
    return result;
    }
    其中 lt_cnt++被汇编为:
    addq $1,lt_cnt(%rip)
    印象中%rip 寄存器在 32 位下是指令指针寄存器,这里的这种用法有没有特别的含义?
    还有这里的加 1 操作可以直接用 inc 指令吗?
    13 条回复    2016-12-28 01:13:42 +08:00
    mjollnirray
        1
    mjollnirray  
       2016-12-25 14:43:07 +08:00
    rip 作为内存引用操作数的一部分是只读的,你直接修改它的值试试,这显然不是普通寄存器的用法
    inc 不会影响到状态寄存器,所以溢出了 FG 也不会告诉你. add 会
    glogo
        2
    glogo  
       2016-12-25 15:56:20 +08:00
    这是第几版那一页的 LZ?发来瞧瞧,忘记了
    Kirscheis
        3
    Kirscheis  
       2016-12-25 16:20:05 +08:00
    不。。 rip 依然是 rip ,这里只是读了一下 rip 而已,这种用法好像在 CSAPP 第三版的 program counter relative addressing 讲了,很久以前看的记不清位置了,翻翻看吧。
    thekll
        4
    thekll  
    OP
       2016-12-25 18:36:41 +08:00 via iPhone
    这是目的操作数,怎么能只是读一下呢?@Kirscheis
    第三版 3.6.5 。 @glogo
    XiaoxiaoPu
        5
    XiaoxiaoPu  
       2016-12-25 18:40:56 +08:00
    @thekll 这里是寄存器相对寻址, rip 相当于一个指针。这种用法的好处是重定向操作更简单了。可以看一下 https://www.polarxiong.com/archives/x64%E4%B8%8BPIC%E7%9A%84%E6%96%B0%E5%AF%BB%E5%9D%80%E6%96%B9%E5%BC%8F-RIP%E7%9B%B8%E5%AF%B9%E5%AF%BB%E5%9D%80.html
    thekll
        6
    thekll  
    OP
       2016-12-25 18:41:36 +08:00 via iPhone
    @Kirscheis,上面说错了,(%rip)是内存引用。
    thekll
        7
    thekll  
    OP
       2016-12-25 18:43:37 +08:00 via iPhone
    @XiaoxiaoPu 嗯,刚回复完就发现我理解错了。
    thekll
        8
    thekll  
    OP
       2016-12-25 18:53:45 +08:00 via iPhone
    @XiaoxiaoPu 我的重点是为什么 c 语句 lt_cnt++;会被编译为汇编语句: addq $1,lt_cnt(%rip) ?
    XiaoxiaoPu
        9
    XiaoxiaoPu  
       2016-12-25 18:59:00 +08:00
    @thekll 额,哪里有疑问?
    yangff
        10
    yangff  
       2016-12-25 19:58:10 +08:00
    @thekll 位置无关代码
    mjollnirray
        11
    mjollnirray  
       2016-12-26 13:59:22 +08:00
    说错了, inc/dec 不会影响状态寄存器的进位位,但是会影响零位和溢出标志
    elevenily
        12
    elevenily  
       2016-12-26 17:11:51 +08:00 via iPhone
    RIP 是 64 位的, EIP 是 32 位的。在这里用 RIP 是 position-independent 的用法,用于 ELF relocation 。
    thekll
        13
    thekll  
    OP
       2016-12-28 01:13:42 +08:00
    @XiaoxiaoPu 因为之前没有任何汇编语法基础,没有理解变量符号 lt_cnt 在语句“ addq $1,lt_cnt(%rip)”中的真正含义。
    想当然的以为就是变量的值(contents of memory location),但在内存寻址的操作数中,其含义实际是指变量地址,对吗?
    变量符号还有两外两种用法,含义又有区别:
    movl var, %eax /值
    movl $var, %eax /地址

    AT&T 的汇编语法参考我只找到这个( 32 位):
    http://docs.oracle.com/cd/E19253-01/817-5477/817-5477.pdf
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   902 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:05 · PVG 04:05 · LAX 12:05 · JFK 15:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.