GCC未优化汇编处理short int加减运算的指令逻辑问询
汇编代码逐行解释
前置背景
对应C代码
typedef struct { short int a1; short int a2;} st1; typedef struct { int sum; int diff;} st2; st2 test (st1 s1) { st2 store; store.sum = s1.a1 + s1.a2; store.diff = s1.a1 - s1.a2; return store; }
基础规则说明(32位x86未优化编译场景)
- 进入函数后
%ebp为栈基址,8(%ebp)是调用方传入的st2返回值结构体的首地址 12(%ebp)对应入参st1的成员a1(2字节short类型),14(%ebp)对应入参st1的成员a2(2字节short类型)- C语言存在整型提升规则:short类型参与算术运算前,会先转换为32位int类型再做计算,你观察到的特殊处理就是这个规则的汇编实现
逐行指令解释
第5~10行:对应store.sum = s1.a1 + s1.a2逻辑
- 第5行
movzwl 12(%ebp), %eax:将栈上12(%ebp)处的2字节a1值零扩展到32位存入%eax,仅保留a1的有效内容,过滤栈上的脏数据 - 第6行
movswl %ax, %edx:将%ax中存储的16位有符号a1值符号扩展为32位int存入%edx,完成short到int的整型提升 - 第7行
movzwl 14(%ebp), %eax:将栈上14(%ebp)处的2字节a2值零扩展到32位存入%eax - 第8行
cwtl:将%ax中存储的16位有符号a2值符号扩展为32位int存入%eax,同样完成整型提升 - 第9行
addl %edx, %eax:两个32位int相加,结果(sum值)存入%eax - 第10行
movl %eax, -8(%ebp):将sum值存入局部变量store的sum成员(栈上-8(%ebp)位置)
第11~14行:对应store.diff = s1.a1 - s1.a2逻辑
未优化编译不会复用之前寄存器里的a1、a2值,所以会重新加载并做整型提升:
- 第11行
movzwl 12(%ebp), %eax:再次零扩展加载a1的2字节到%eax - 第12行
movswl %ax, %edx:将a1符号扩展为32位int存入%edx - 第13行
movzwl 14(%ebp), %eax:再次零扩展加载a2的2字节到%eax - 第14行
cwtl:将a2符号扩展为32位int存入%eax
后续15~17行就是计算差值并存入store的diff成员,逻辑和加法部分一致。
内容的提问来源于stack exchange,提问作者user13873843
相关产品推荐
相关产品推荐

