C switch 语句的汇编 - 它是如何工作的? [英] Assembly for a C switch statement - how does it work?
问题描述
我正在阅读一本关于汇编 switch 语句的书,当输入 n 为 case: 100、102、103、104、106 时,代码具有案例/分支.它通过从 n 中减去 100 来简化跳转表,然后如果结果在6以上,则转到L2中的默认情况,否则将转到与%eax中的值匹配的相应分支.
I am reading a book about assembly switch statement, the code has cases/branches when the input n is case: 100, 102, 103, 104, 106. It simplified the jump table by subtracting 100 from n and then if the result is above 6, it goes to the default case in L2, Otherwise it will go to the corresponding branches that match the value in %eax.
我的问题是:
如果是这样,如果跳转表的索引保存在
%eax
jmp *.L7(,%eax)吗>?
if so, isn't line 7 suppose to be
jmp *.L7(,%eax)
if the index of jump table is held in%eax
?
为什么他们在第 5 行通过 ja .L2
将数字更改为无符号数?
And why did they change the number into unsigned in line 5 by doing ja .L2
?
int x
在 %ebp+8
,int n
在 %ebp+12
movl 8(%ebp), %edx
movl 12(%ebp), %eax
subl $100, %eax
cmpl $6, %eax
ja .L2
jmp *.L7(,%eax,4)
.L2:
movl $0, %eax
jmp .L8
.L5:
movl %edx, %eax
jmp .L9
.L3:
leal (%edx,%edx,2), %eax
leal (%edx,%eax,4), %eax
jmp .L8
.L4:
leal 10(%edx), %eax
.L9:
addl $11, %eax
jmp .L8
.L6:
movl %edx, %eax
imull %edx, %eax
.L8:
跳表:
.section .rodata
.align 4 Align
.L7:
.long .L3 //Case 100: loc_A
.long .L2 //Case 101: loc_def
.long .L4 //Case 102: loc_B
.long .L5 //Case 103: loc_C
.long .L6 //Case 104: loc_D
.long .L2 //Case 105: loc_def
.long .L6 //Case 106: loc_D
推荐答案
如果跳转表的索引保存在
%eax
中,第7行不应该是jmp *.L7(,%eax)
吗?
isn't line 7 suppose to be
jmp *.L7(,%eax)
if the index of jump table is held in%eax
?
跳转表中的每一项都是一个long
,即4个字节.因此 eax
被缩放 4.
Each entry in the jump table is a long
, which is 4 bytes. Hence eax
is scaled by 4.
为什么他们在第 5 行通过 ja .L2
将数字更改为无符号数?
And why did they changed the number into unsigned in line 5 by doing
ja .L2
?
关键是要排除小于 100 和大于 106 的任何数字.我认为它如何排除大于 106 的值是显而易见的.
The point is to exclude any number that's less than 100 and greater than 106. I assume it's obvious how it excludes values greater than 106.
假设 n
小于 100,例如99. 如果我们再减去 100,我们得到 -1,当被视为一个无符号的 32 位值时,它是 4294967295,这显然是高于"6,然后跳转到 .L2
就像它应该的那样.
So let's say n
was less than 100, e.g. 99. If we then subtract 100 from that we get -1, which when viewed as an unsigned 32-bit value is 4294967295, which is obviously "above" 6, and the jump to .L2
is taken like it should.
subl $100, %eax ; eax = 99-100 == -1
cmpl $6, %eax ; set flags based on -1 - 6 == -7 => ZF=0 and CF=0
ja .L2 ; jump if ZF=0 and CF=0
这篇关于C switch 语句的汇编 - 它是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!