C switch 语句的汇编 - 它是如何工作的? [英] Assembly for a C switch statement - how does it work?

查看:13
本文介绍了C switch 语句的汇编 - 它是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读一本关于汇编 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.

我的问题是:

  1. 如果是这样,如果跳转表的索引保存在%eaxjmp *.L7(,%eax)吗>?

  1. 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+8int 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆