在以下说明中,addq如何工作?它只有一个操作数,书中声称它增加%rdx,但%rdx不在此指令中。我很困惑......
这来自Computer Systems A Programmers Perspective,3rd Edition。
答案 0 :(得分: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 $0, %edx
jmp .L2
.L3:
movl cnt(%rip), %eax
addl $1, %eax
movl %eax, cnt(%rip)
addl $1, %edx
.L2:
cmpl %ecx, %edx
jl .L3
movl $0, %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 $40, %rsp
.cfi_def_cfa_offset 48
cmpl $2, %edi
je .L5
movq (%rsi), %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %edi
call exit
.L5:
movq 8(%rsi), %rdi
movl $10, %edx
movl $0, %esi
call strtol
movl %eax, 28(%rsp)
leaq 28(%rsp), %rcx
movl $thread, %edx
movl $0, %esi
leaq 16(%rsp), %rdi
call pthread_create
leaq 28(%rsp), %rcx
movl $thread, %edx
movl $0, %esi
leaq 8(%rsp), %rdi
call pthread_create
movl $0, %esi
movq 16(%rsp), %rdi
call pthread_join
movl $0, %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 $0, %eax
call printf
.L7:
movl $0, %edi
call exit
.L6:
movl cnt(%rip), %esi
movl $.LC2, %edi
movl $0, %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
所以它证实了这本书的错误。