【发布时间】:2019-11-26 18:12:06
【问题描述】:
在汇编中,如果我有一个 JUMP 表,其地址超过 2000 个标签:
.TABLE:
DD .case0
DD .case1
DD .case2
DD .case3
DD .case4
...
...
...
DD .case2000
哪种方式更适合寻址跳转:
方式一:
mov r12d, .TABLE ; r12d or any other registers
mov ebx, [r13d] ; r13d holds the id of case * 4 so we don't need to '4 * ebx'
add ebx, r12d ; ebx = address for Jumping
jmp ebx
方式 2:(与方式 1 相同,但将 'add ebx, r12d' 删除并更改为 'jmp [ebx+r12d]')
mov r12d, .TABLE ; r12d or any other registers
mov ebx, [r13d] ; r13d holds the id of case * 4 so we don't need to '4 * ebx'
jmp [ebx+r12d]
方式 3:
mov ebx, [r13d] ; r13d holds the id of case * 4 so we don't need to '4 * ebx'
jmp [ebx + .TABLE]
在“方式 1”中,由于额外的功能,我们有源代码大小问题,但我认为它在跳转方面比其他方式有更好的性能,因为我将有大约 2000 次跳转(不规则跳转(可能是从 case0 到 case1000或...)
那么对于跳跃性能,在有很多 JUMP 的源代码中,哪种方式更好?
【问题讨论】:
-
方式 1 应该以
jmp [ebx]结尾,否则它会跳到跳转表的中间。此外,如果您使用仅在 64 位模式下可用的寄存器,您可能应该进行 64 位地址计算。 -
别想太多。采用第三种方式,指令最少。
-
@1201ProgramAlarm 最少的指令并不总是一个解决方案!
-
@Ross Ridge r13d 不是 64 位模式寄存器!!!! r13d 的 64 位寄存器是 r13 !!!!
-
R13D 是一个 32 位寄存器,仅在 64 位模式下可用。 !!!!
标签: performance assembly x86 micro-optimization