Inline Assemble Code - A problem relevant to register usage
2015-07-14 13:42
477 查看
1. Source code as followings
#include <stdio.h>
int main()
{
int arg1, arg2, add, sub, mul, quo, rem ;
printf( "Enter two integer numbers : " );
scanf( "%d%d", &arg1, &arg2 );
__asm__ ( "movl $0, %%edx;"
"movl %2, %%eax;"
"movl %3, %%ebx;"
"idivl %%ebx;" : "=a" (quo), "=d" (rem) : "g" (arg1), "g" (arg2) );
printf( "%d / %d = %d\n", arg1, arg2, quo );
printf( "%d %% %d = %d\n", arg1, arg2, rem );
return 0 ;
}
2. compile
gcc -o tt1.x tt1.c
3. run
./tt1.x
Floating point exception (core dumped)
4. Root Cause
objdump -D tt1.x >111
vi 111, you will see below
4005c9: e8 d2 fe ff ff callq 4004a0 <__isoc99_scanf@plt>
4005ce: 8b 45 f0 mov -0x10(%rbp),%eax
4005d1: 8b 55 f4 mov -0xc(%rbp),%edx
4005d4: ba 00 00 00 00 mov $0x0,%edx
4005d9: 89 c0 mov %eax,%eax
4005db: 89 d3 mov %edx,%ebx
4005dd: f7 fb idiv %ebx
4005df: 89 45 f8 mov %eax,-0x8(%rbp)
4005e2: 89 55 fc mov %edx,-0x4(%rbp)
4005e5: 8b 55 f4 mov -0xc(%rbp),%edx
4005e8: 8b 45 f0 mov -0x10(%rbp),%eax
4005eb: 8b 4d f8 mov -0x8(%rbp),%ecx
5. Statement
The root cause is that arg2 use register edx, but edx
is cleared zero before idiv
6. improvement
Change arg2 to memory location rather than register.
#include <stdio.h>
int main()
{
int arg1, arg2, add, sub, mul, quo, rem ;
printf( "Enter two integer numbers : " );
scanf( "%d%d", &arg1, &arg2 );
__asm__ ( "movl $0, %%edx;"
"movl %2, %%eax;"
"movl %3, %%ebx;"
"idivl %%ebx;" : "=a" (quo), "=d" (rem) : "m" (arg1), "m" (arg2) );
printf( "%d / %d = %d\n", arg1, arg2, quo );
printf( "%d %% %d = %d\n", arg1, arg2, rem );
return 0 ;
}
#include <stdio.h>
int main()
{
int arg1, arg2, add, sub, mul, quo, rem ;
printf( "Enter two integer numbers : " );
scanf( "%d%d", &arg1, &arg2 );
__asm__ ( "movl $0, %%edx;"
"movl %2, %%eax;"
"movl %3, %%ebx;"
"idivl %%ebx;" : "=a" (quo), "=d" (rem) : "g" (arg1), "g" (arg2) );
printf( "%d / %d = %d\n", arg1, arg2, quo );
printf( "%d %% %d = %d\n", arg1, arg2, rem );
return 0 ;
}
2. compile
gcc -o tt1.x tt1.c
3. run
./tt1.x
Floating point exception (core dumped)
4. Root Cause
objdump -D tt1.x >111
vi 111, you will see below
4005c9: e8 d2 fe ff ff callq 4004a0 <__isoc99_scanf@plt>
4005ce: 8b 45 f0 mov -0x10(%rbp),%eax
4005d1: 8b 55 f4 mov -0xc(%rbp),%edx
4005d4: ba 00 00 00 00 mov $0x0,%edx
4005d9: 89 c0 mov %eax,%eax
4005db: 89 d3 mov %edx,%ebx
4005dd: f7 fb idiv %ebx
4005df: 89 45 f8 mov %eax,-0x8(%rbp)
4005e2: 89 55 fc mov %edx,-0x4(%rbp)
4005e5: 8b 55 f4 mov -0xc(%rbp),%edx
4005e8: 8b 45 f0 mov -0x10(%rbp),%eax
4005eb: 8b 4d f8 mov -0x8(%rbp),%ecx
5. Statement
The root cause is that arg2 use register edx, but edx
is cleared zero before idiv
6. improvement
Change arg2 to memory location rather than register.
#include <stdio.h>
int main()
{
int arg1, arg2, add, sub, mul, quo, rem ;
printf( "Enter two integer numbers : " );
scanf( "%d%d", &arg1, &arg2 );
__asm__ ( "movl $0, %%edx;"
"movl %2, %%eax;"
"movl %3, %%ebx;"
"idivl %%ebx;" : "=a" (quo), "=d" (rem) : "m" (arg1), "m" (arg2) );
printf( "%d / %d = %d\n", arg1, arg2, quo );
printf( "%d %% %d = %d\n", arg1, arg2, rem );
return 0 ;
}
相关文章推荐
- BZOJ 1013 [JSOI2008]球形空间产生器sphere
- LeetCode - Binary Search Tree Iterator
- tinyMCE粘贴word/html时去掉文本里的样式
- 大话设计模式(十一 三层架构,分层开发)
- VC 使用OnCtlColor函数来改变控件颜色
- SQL Server Profiler:使用方法和指标说明
- web基础知识
- H5+ 分享到微信、朋友圈代码示例
- phpmyadmin修改文件上传大小限制
- 傻啵似的学、、、、(简单文件权限)
- NYOJ 6 喷水装置(一)
- codeforces 520B Two Buttons BFS
- Navicat:excel数据导入mysql数据库
- 第二篇:opencv纠错,R6010-abort() has been called
- C++ 11新特性:移动构造函数和移动赋值操作符
- 跑步
- display:flex 多栏多列布局
- css3倒影
- 使用Bootstrap框架制作响应式移动网页
- 机器视觉系统中相机的分辨率怎么选择?