在汇编语言中确定返回值时遇到问题
Posted
技术标签:
【中文标题】在汇编语言中确定返回值时遇到问题【英文标题】:Having trouble determining the return value in assembly language 【发布时间】:2022-01-14 09:58:21 【问题描述】:我是汇编语言/代码领域的新手。我觉得很难理解,但我尽力了。我只是在处理作业需要回答的一些问题时遇到了问题。
如果我通过 echo $? 我需要找出特定程序的返回值?作为终端中的命令,我得到 10 作为答案。但是我老师的答题纸上说答案是 9。
我需要通过检查汇编代码的转储来找出(同一程序的)main 的返回值。同样,我认为答案是 10,因为 0xa = 10。但是,答题纸再次说答案是 9。我是否需要默认从返回值中减去 1 或其他什么?如果有,为什么?
0x000000000000069f <+0>: 55 push %rbp
0x00000000000006a0 <+1>: 48 89 e5 mov %rsp,%rbp
0x00000000000006a3 <+4>: bf 05 00 00 00 mov $0x5,%edi
0x00000000000006a8 <+9>: e8 9d ff ff ff callq 0x64a <okfisbup>
0x00000000000006ad <+14>: b8 0a 00 00 00 mov $0xa,%eax
0x00000000000006b2 <+19>: 5d pop %rbp
0x00000000000006b3 <+20>: c3 retq
当我运行程序时,使用 ./(filename),这就是我得到的。
iteratie: 1, buffer address : 0x7ffe4052d0e0
iteratie: 2, buffer address : 0x7ffe4052d1c0
iteratie: 3, buffer address : 0x7ffe4052d2a0
iteratie: 4, buffer address : 0x7ffe4052d380
iteratie: 5, buffer address : 0x7ffe4052d460
这是 okfisbup 的转储:
0x000000000000064a <+0>: push %rbp
0x000000000000064b <+1>: mov %rsp,%rbp
0x000000000000064e <+4>: sub $0xd0,%rsp
0x0000000000000655 <+11>: mov %edi,%eax
0x0000000000000657 <+13>: mov %al,-0xc4(%rbp)
0x000000000000065d <+19>: movzbl -0xc4(%rbp),%eax
0x0000000000000664 <+26>: sub $0x1,%eax
0x0000000000000667 <+29>: mov %al,-0x1(%rbp)
0x000000000000066a <+32>: cmpb $0x0,-0x1(%rbp)
0x000000000000066e <+36>: je 0x67b <okfisbup+49>
0x0000000000000670 <+38>: movzbl -0x1(%rbp),%eax
0x0000000000000674 <+42>: mov %eax,%edi
0x0000000000000676 <+44>: callq 0x64a <okfisbup>
0x000000000000067b <+49>: movzbl -0xc4(%rbp),%eax
0x0000000000000682 <+56>: lea -0xc0(%rbp),%rdx
0x0000000000000689 <+63>: mov %eax,%esi
0x000000000000068b <+65>: lea 0xb6(%rip),%rdi # 0x748
0x0000000000000692 <+72>: mov $0x0,%eax
0x0000000000000697 <+77>: callq 0x520 <printf@plt>
0x000000000000069c <+82>: nop
0x000000000000069d <+83>: leaveq
0x000000000000069e <+84>: retq
【问题讨论】:
从你的散文来看,我认为你是对的。不过,我们还没有看到大会。 -- 让你的老师解释为什么应该是 9。 如果是 10,那么它必须是 10。没有添加或减去任何内容 输出应该是 10。你的老师/导师或任何应该解释你为什么她/他认为输出是 9。这是她/他的工作。 OTOH,我们不知道okfisbup
是什么……有什么你没有告诉我们的吗?
术语:echo $?
显示最后一个命令的“退出状态”。程序具有退出状态,它来自于 _exit()
系统调用的 arg 或由于信号导致的异常终止。从main
返回确实会导致 main 的返回值被传递给退出系统调用,因此返回值成为退出状态。 (或者至少是它的低 8 位。)
感谢您发布okfisbup
的转储。这个函数似乎做了一些递归的东西打印一些似乎与实际问题无关的缓冲区地址。它绝对不会调用exit(9)
。你需要问问你的老师。从我们可以看出你的老师错了。
【参考方案1】:
movq $0xa, %eax
popq rbp
retq
返回值为10
。答题卡错了。
如果没有给出代码,并且使用 $?透露了 10 个。这就够了。
编辑:okfisbup
的反汇编现已发布。它只调用自己和printf
。
【讨论】:
我编辑了我的问题,添加了 okfisbup 的 disas 转储。我希望它有所帮助。很抱歉造成混乱。 我想知道okfisbup
玩有趣的游戏,比如弄乱它的返回地址以跳过mov $0xa, %eax
,但似乎没有类似的东西。只是一个非常无聊且未优化的函数,在打印其他未使用的本地数组的地址时会递归。
@NateEldredge:如果这是我的答案,我会对一项明显不公平的家庭作业大声疾呼。它调用 exit 至少是一个合理的家庭作业。【参考方案2】:
返回值为10,你的老师错了
https://godbolt.org/z/8YsnvPahM
int main(void)
return 10;
main:
pushq %rbp
movq %rsp, %rbp
movl $10, %eax
popq %rbp
ret
【讨论】:
以上是关于在汇编语言中确定返回值时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章
使用keil编程常遇到c语言问题;main被重复定义了,如何破?