这个 x86-64 addq 指令是什么意思,它只有一个操作数? (摘自CSAPP书第3版)

What does this x86-64 addq instruction mean, which only have one operand? (From CSAPP book 3rd Edition)

在下面的指令中,addq是如何工作的?它只有一个操作数,书中声称它递增 %rdx,但 %rdx 不在此指令中。我很困惑...

这是来自 Computer Systems A Programmers Perspective,第 3 版一书。

正如@Jester 在评论中指出的那样。这确实是一个错误。 我实际上输入了程序并使用 linux 上的 gcc 编译了它。下面是结果。

C程序:badcnt.c

/*
 * badcnt.c - An improperly synchronized counter program
 */
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>

void *thread(void *vargp);  /* Thread routine prototype */

/* Global shared variable */
volatile int cnt = 0; /* Counter */

int main(int argc, char **argv)
{
  int niters;
  pthread_t tid1, tid2;

  /* Check input argument */
  if (argc != 2) {
    printf("usage: %s <niters>\n", argv[0]);
    exit(0);
  }
  niters = atoi(argv[1]);

  /* Create threads and wait for them to finish */
  pthread_create(&tid1, NULL, thread, &niters);
  pthread_create(&tid2, NULL, thread, &niters);
  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);

  /* Check result */
  if (cnt != (2 * niters))
    printf("BOOM! cnt=%d\n", cnt);
  else
    printf("OK cnt=%d\n", cnt);
  exit(0);
}

/* Thread routine */
void *thread(void *vargp)
{
  int i, niters = *((int *)vargp);

  for (i = 0; i < niters; i++)
    cnt++;

  return NULL;
}

使用 gcc 6.3.0 编译

$ gcc -pthread -Og -S badcnt.c

以下是badcnt.s

中的内容
        .file   "badcnt.c"
        .text
        .globl  thread
        .type   thread, @function
thread:
.LFB20:
        .cfi_startproc
        movl    (%rdi), %ecx
        movl    [=11=], %edx
        jmp     .L2
.L3:
        movl    cnt(%rip), %eax
        addl    , %eax
        movl    %eax, cnt(%rip)
        addl    , %edx
.L2:
        cmpl    %ecx, %edx
        jl      .L3
        movl    [=11=], %eax
        ret
        .cfi_endproc
.LFE20:
        .size   thread, .-thread
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "usage: %s <niters>\n"
.LC1:
        .string "BOOM! cnt=%d\n"
.LC2:
        .string "OK cnt=%d\n"
        .text
        .globl  main
        .type   main, @function
main:
.LFB19:
        .cfi_startproc
        subq    , %rsp
        .cfi_def_cfa_offset 48
        cmpl    , %edi
        je      .L5
        movq    (%rsi), %rsi
        movl    $.LC0, %edi
        movl    [=11=], %eax
        call    printf
        movl    [=11=], %edi
        call    exit
.L5:
        movq    8(%rsi), %rdi
        movl    , %edx
        movl    [=11=], %esi
        call    strtol
        movl    %eax, 28(%rsp)
        leaq    28(%rsp), %rcx
        movl    $thread, %edx
        movl    [=11=], %esi
        leaq    16(%rsp), %rdi
        call    pthread_create
        leaq    28(%rsp), %rcx
        movl    $thread, %edx
        movl    [=11=], %esi
        leaq    8(%rsp), %rdi
        call    pthread_create
        movl    [=11=], %esi
        movq    16(%rsp), %rdi
        call    pthread_join
        movl    [=11=], %esi
        movq    8(%rsp), %rdi
        call    pthread_join
        movl    28(%rsp), %eax
        addl    %eax, %eax
        movl    cnt(%rip), %edx
        cmpl    %edx, %eax
        je      .L6
        movl    cnt(%rip), %esi
        movl    $.LC1, %edi
        movl    [=11=], %eax
        call    printf
.L7:
        movl    [=11=], %edi
        call    exit
.L6:
        movl    cnt(%rip), %esi
        movl    $.LC2, %edi
        movl    [=11=], %eax
        call    printf
        jmp     .L7
        .cfi_endproc
.LFE19:
        .size   main, .-main
        .globl  cnt
        .bss
        .align 4
        .type   cnt, @object
        .size   cnt, 4
cnt:
        .zero   4
        .ident  "GCC: (GNU) 6.3.0"
        .section        .note.GNU-stack,"",@progbits

所以证实了书上的错误