草庐IT

c - Windows 上的 gcc 生成垃圾? Windows 与 Linux

coder 2024-06-19 原文

我想找出为什么在 Windows 中对同一程序的指令比在 Linux 中多得多。 所以我只用了 int a=0xbeef;printf("test\n");在 C 中并在 Linux 和 Windows 中编译。当我调试和反汇编主机时,我得到了这个: 在 Linux 上:

0x080483e4 <+0>:     push   %ebp
0x080483e5 <+1>:     mov    %esp,%ebp
0x080483e7 <+3>:     and    $0xfffffff0,%esp
0x080483ea <+6>:     sub    $0x20,%esp
0x080483ed <+9>:     movl   $0xbeef,0x1c(%esp)
0x080483f5 <+17>:    movl   $0x80484d0,(%esp)
0x080483fc <+24>:    call   0x8048318 <puts@plt>
0x08048401 <+29>:    leave  
0x08048402 <+30>:    ret 

好的,那很好。我看到 esp 的 movl 0x1c 偏移量将值放在那里。

但在 Windows 中我得到了这个:

0x401290 <main>:        push   %ebp
0x401291 <main+1>:      mov    %esp,%ebp
0x401293 <main+3>:      sub    $0x18,%esp
0x401296 <main+6>:      and    $0xfffffff0,%esp
0x401299 <main+9>:      mov    $0x0,%eax
0x40129e <main+14>:     add    $0xf,%eax
0x4012a1 <main+17>:     add    $0xf,%eax
0x4012a4 <main+20>:     shr    $0x4,%eax
0x4012a7 <main+23>:     shl    $0x4,%eax
0x4012aa <main+26>:     mov    %eax,0xfffffff8(%ebp)
0x4012ad <main+29>:     mov    0xfffffff8(%ebp),%eax
0x4012b0 <main+32>:     call   0x401720 <_alloca>
0x4012b5 <main+37>:     call   0x4013c0 <__main>
0x4012ba <main+42>:     movl   $0xbeef,0xfffffffc(%ebp)
0x4012c1 <main+49>:     movl   $0x403000,(%esp,1)
0x4012c8 <main+56>:     call   0x401810 <printf>
0x4012cd <main+61>:     mov    $0x0,%eax
0x4012d2 <main+66>:     leave
0x4012d3 <main+67>:     ret

首先,我不知道为什么windows编译器(mingw)会生成这么多代码。比 Linux 多 2 倍……这让我思考。还有一件事:从 main+9 到 main+37 我看不出那段代码的意义。

如果有人回答这个问题,我将不胜感激,我只是好奇:)

编辑: 在 linux 上使用 -O3 参数我得到了相同的结果,在 windows 中发生了类似魔术的事情:

0x401290 <main>:        push   %ebp
0x401291 <main+1>:      mov    $0x10,%eax
0x401296 <main+6>:      mov    %esp,%ebp
0x401298 <main+8>:      sub    $0x8,%esp
0x40129b <main+11>:     and    $0xfffffff0,%esp
0x40129e <main+14>:     call   0x401700 <_alloca>
0x4012a3 <main+19>:     call   0x4013a0 <__main>
0x4012a8 <main+24>:     movl   $0x403000,(%esp,1)
0x4012af <main+31>:     call   0x4017f0 <puts>
0x4012b4 <main+36>:     leave
0x4012b5 <main+37>:     xor    %eax,%eax
0x4012b7 <main+39>:     ret

先离开再异或再返回。好的 :D 调用 _alloca 和调用 __main 仍然存在。我不知道什么是 0x401291 <main+1>: mov $0x10,%eax在这里做 :D

最佳答案

你好像是用旧的 3.x 系列 gcc 编译的,你最好升级。较新的版本不调用 alloca。我怀疑 alloca 的特定版本可能使用寄存器约定,因此 mov 0x10,%eax 可能正在为该调用设置参数。

__main 是在 crtbegin.o 中定义的启动函数,它执行全局构造函数并使用 atexit 注册一个将运行全局析构函数的函数.

另请注意,main 得到特殊处理,如堆栈对齐代码和上述初始化。如果您只对代码生成问题感兴趣,那么比较“普通”函数可能是个好主意。

关于c - Windows 上的 gcc 生成垃圾? Windows 与 Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19552816/

有关c - Windows 上的 gcc 生成垃圾? Windows 与 Linux的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  5. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  6. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  7. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  8. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  9. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  10. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

随机推荐