2

我正在尝试使用 rdtscp 计时子程序。这是我的程序:

; Setting up time
rdtscp                      ; Getting time
push rax                    ; Saving timestamp

; for(r9=0; r9<LOOP_SIZE; r9++)
mov r9, 0
lup0:
call subr
inc r9
cmp r9, LOOP_SIZE
jnz lup0

; Calculating time taken
pop rbx                     ; Loading old time
rdtscp                      ; Getting time
sub rax, rbx                ; Calculating difference

如果LOOP_SIZE足够小,我会得到一致且预期的结果。但是,当我让它足够大(大约 10^9)时,我会从 10^9 飙升到 10^20。

; Result with "LOOP_SIZE equ 100000000"
971597237
; Result with "LOOP_SIZE equ 1000000000"
18446744072281657066

我用来显示数字的方法将它们显示为无符号,所以我想显示的大数字实际上是一个负数并且发生了溢出。但是,971597237甚至没有接近 64 位整数限制,所以,假设问题是溢出,为什么会发生呢?

4

1 回答 1

7

问题是,根据文档,即使在 64 位模式下, 的值rdtscp也不是存储在rax,而是在edx:eax(这意味着高位打开edx,低位打开)。eax

所以,如果你想在 上使用完整的 64 位值rax,你必须从 移动高位edx

; Setting up time
rdtscp                      ; Getting time
shl rdx, 32                 ; Shifting rdx to the correct bit position
add rax, rdx                ; Adding both to make timestamp
push rax                    ; Saving timestamp

; [...stuff...]

; Calculating time taken
rdtscp                      ; Getting time
pop rbx                     ; Loading old time (below rdtscp)
shl rdx, 32                 ; Shifting rdx to the correct bit position
add rax, rdx                ; Adding both to make timestamp
sub rax, rbx                ; Calculating difference

编辑:pop rbx下移一行,在rdtscp. 正如 Peter 所指出的,一些寄存器(rax、rdx 和 rcx)可能会被rdtscp. 在您的示例中,这不是问题,但是如果您决定改为pop rcx那里,那么它可能会被 覆盖rdtscp,因此最好只在其后弹出堆栈。


此外,您可以通过将旧时间戳保存在子程序不使用的寄存器中来避免两次调用堆栈:

; Setting up time
rdtscp                      ; Getting time
shl rdx, 32                 ; Shifting rdx to the correct bit position
lea r12, [rdx + rax]        ; Adding both to make timestamp, and saving it

; [...stuff (that doesn't use r12)...]

; Calculating time taken
rdtscp                      ; Getting time
shl rdx, 32                 ; Shifting rdx to the correct bit position
add rax, rdx                ; Adding both to make timestamp
sub rax, r12                ; Calculating difference
于 2020-11-19T03:18:03.707 回答