汇编一个C switch语句-它是如何工作的? [英] Assembly for a C switch statement - how does it work?
问题描述
我正在读一本关于汇编开关语句的书,当输入n为大小写时,代码具有大小写/分支: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
中,第7行是否不是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
?
为什么他们通过执行ja .L2
将数字更改为第5行中的无符号?
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.
为什么他们通过执行
ja .L2
将数字更改为第5行中的无符号?
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屋!