当前位置: 首页 > 知识库问答 >
问题:

Noob ASM问题

东门彬
2023-03-14
.data
helloworld:
    .asciz "printf test! %i\n"
.text
.globl main
main:
    push $0x40
    push $helloworld
    call printf
    mov $0, %eax
    ret

test.working.s:

.data
helloworld:
    .asciz "printf test! %i\n"
.text
.globl main
main:
    mov $0x40, %esi
    mov $printf_test, %edi
    mov $0x0, %eax
    call printf
    mov $0, %eax
    ret

compile.sh:

rm test
gcc test.s -o test -lc
chmod 777 test
./test

Test.s立即分段故障。我使用eclipse中的反汇编窗口创建了test.working.s,并编写了一个小的C程序来使用printf打印一些东西。

s(我想这是在1中回答的,但如果不是...)通过更改寄存器调用printf,而不是通过将内容推入堆栈。我想这是因为它更快?在调用c函数时,您如何知道何时进行此操作以及以何种顺序进行?

这在Windows x86-64上也行得通吗?我明白printf的操作可能不同,但如果我在printf之后清理和恢复寄存器,我应该没事吧?

您应该如何清理和恢复寄存器?根据http://www.cs.uaf.edu/2005/fall/cs301/support/x86/,它说我“必须保存%esp,%ebp,%esi,%edi”。是指这样一个事实,当我写一个函数时,这些寄存器必须按照它们进来的方式返回,还是我应该在调用一个函数之前保存它们。它可能是前者,因为%ESP,但只是检查!

为任何帮助干杯!

共有1个答案

云何平
2023-03-14

>

  • ,因为在64位模式下,应该在寄存器中传递参数,而不是在堆栈中传递参数(请参见此答案)。即使不是这样,您也没有push$0x40的大小说明符,因此很可能只推送一个16位的值,而不是32位的值。

    堆栈的顶部将包含对main的调用来自何处的返回地址(例如__libc_start_main)。下面是argcargv。您不需要弹出其中任何一个(您不应该弹出其中任何一个,因为您需要保留返回地址)。

    32位值1将被写入为0x00000001(最重要的nybble在左边),并以小端配置存储为(低地址)01 00 00 00(高地址)。由于通常是先用最高有效位数来写数字,而不是根据它们的存储方式来写,所以将rax描述写成RR RR RR RR RR EE EE xxxx是有意义的,如果不清楚顺序是什么,还可以使用位索引标记。


    同样,这是64位x86代码的调用约定,如本答案所述。

    因为Windows使用的64位调用约定略有不同(用于传递参数的寄存器是RCX、RDX、R8、R9)。

    例如,通过将它们保存在堆栈中。有被调用者保存的寄存器和调用者保存的寄存器。
    被调用者(被调用的函数)必须保存某些寄存器并在返回之前还原它们,以遵守调用约定。对于Linux类型系统上的64位程序,它是RBX、RBP、R12-R15(在64位Windows上,这还包括RSIRDI)。
    调用方(调用函数的代码)必须考虑某些寄存器是易失性的(即可以由函数更改),如果函数返回后需要它们的值,就应该保存和恢复它们。在Linux类型的系统中,它们是RAX、RCX、RDX、RSI、RDI、R8-R11

    GNU汇编程序应该支持-M32命令行选项,以指定您正在汇编32位代码。

    是的。

  •  类似资料:
    • 问题内容: 包括: all Spring libs, Apache Tomcat 7.0 library 在构建路径中 但它仍然给出错误: 在“ org.sprintframework.web-3.1.0.M1.jar”中,我可以看到“ org.springframework.web.context.ContextLoaderListener”。 Google上的某个人说应该包含spring.ja

    • 问题内容: 我使用非常简单的代码返回XML 但是,出现以下错误 请帮忙。谢谢 问题答案: 运行时出现NoSuchMethodError表示你使用的库版本与生成代码所针对的版本不同。 在你的情况下,Spring是元凶。在运行时检查类路径上的内容,并确保以下各项: 版本与编译时间罐相同 如果存在多个版本,请删除不需要的版本

    • 问题内容: 我不明白注释和之间的实际区别是什么? 扩展名还是它们具有完全不同的含义?什么时候应该使用它们?在服务层中使用Spring ,在DAO 中使用javax? 谢谢回答。 问题答案: 几年前,Spring定义了自己的Transactional注释以使Spring bean方法具有事务性。 Java EE 7终于做了同样的事情,现在除了EJB方法外,还允许CDI bean方法是事务性的。因此,

    • 我在CentOS虚拟机中安装了RabbitMQ,该虚拟机的网络适配器被定义为Bridge。我正在尝试配置RabbitMQ管理,以便通过机器的IP地址访问WebApp。配置如下:

    • 这个FAQ的最新版本总是可以从Apache主站点得到,位于<http://httpd.apache.org/docs/2.2/faq/> 如果你的问题在这里没有找到答案,你也可以看看Apache 1.3 FAQ ,看你的问题是否在那里有了答案。 主题 背景 关于 Apache HTTP Server 的背景知识。 支持 我遇到问题该怎么办? 错误信息 这些错误信息是什么意思? 背景 什么是Apac

    • 发布问题 更新问题 设置问题悬赏 获取问题列表 获取一个问题详情 删除一个问题 获取用户发布的问题列表 发布问题 POST /questions 输入 字段 类型 描述 subject 字符串 必须,问题主题或者说标题,不能超过 255 字节 ,必须以 ? 结尾。(不区分全角或者半角) topics 数组 必须,绑定的话题,数组子节点必须符合 { "id": 1 } 的格式。 body 字符串

    • 问题内容: 我简直不敢相信我网站上正在发生的事情。当我添加此行时: 一切正常。如果我不这样做,CSS就会“混乱”,一切都会变得不同,布局也会变得“丑陋”。 这条线如何解决所有问题? 问题答案: 您正在将HTML与XHTML混合使用。 通常,声明用于区分HTMLish语言的版本(在这种情况下为HTML或XHTML)。 不同的标记语言将表现不同。我最喜欢的例子是。在浏览器中查看以下内容: XHTML

    • 我试图在fabric rocket chat上联系,但没有得到太多帮助,因此在SO上发布了它。我有以下疑问: 我们是否可以在链码内访问块高度(我知道这在客户端是可行的,但在链码内是否可能) 可以从链码中的正在进行的事务调用新事务吗? 想知道hyperledger Fabric中存储的数据的历史记录在哪里 我们可以根据链码中的transactionid进行查询吗? 在fabric链码中编写调度程序是