我正在读一本关于程序集切换语句的书,当输入n为大小写时,代码有case / branches:100,102,103,104,106。它通过从n减去100来简化跳转表,然后如果结果大于6,它转到L2中的默认情况,否则它将转到与%eax中的值匹配的相应分支。
我的问题是:
如果是,如果跳转表的索引保存在jmp *.L7(,%eax)
中,则第7行不是%eax
?
为什么他们通过ja .L2
将数字更改为第5行中的无符号?
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
答案 0 :(得分:3)
如果跳转表的索引保存在jmp *.L7(,%eax)
中,第7行是不是
%eax
?
跳转表中的每个条目都是long
,即4个字节。因此,eax
缩放为4。
为什么他们通过
ja .L2
将数字改为第5行中的无符号?
重点是排除任何小于100且大于106的数字。我认为它排除了大于106的值是显而易见的。
所以,让我们说n
小于100,例如99.如果我们从那里减去100,我们得到-1,当被视为无符号的32位值时是4294967295,这显然是"高于" 6,跳转到.L2
就像它应该的那样。
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