我对汇编语言很陌生。我有以下汇编代码:
.intel_syntax noprefix
.bits 32
.global asm0
asm0:
push ebp
mov ebp,esp
mov eax,DWORD PTR [ebp+0x8]
mov ebx,DWORD PTR [ebp+0xc]
mov eax,ebx
mov esp,ebp
pop ebp
ret我想知道下面的命令返回了什么: asm0(0x2a,0x4f)。
我正在运行Ubuntu,我已经下载了NASM。我在这里读到了汇编代码的语法:syntax.htm,但我仍然无法理解这一点。我已经用C++编写了三年代码,但这仍然让我感到困惑。有更多经验的人能帮我解决这个问题吗?
编辑:上面的代码是推送和移动,所以它看起来有点像堆栈数据结构?然后它会在最后返回。但是,这个函数没有参数。这怎么做呢?
运行gcc -m32 -g main.c汇编.s时出现的错误消息
myName@myName:~/Downloads$ gcc -m32 -g main.c file.S
main.c: In function ‘main’:
main.c:5:17: warning: implicit declaration of function ‘asm0’ [-Wimplicit-
function-declaration]
printf("%d", asm0(123,456));
^~~~
file.S: Assembler messages:
file.S:2: Error: unknown pseudo-op: `.bits'发布于 2018-10-06 02:12:40
您的函数在堆栈上查找它的2个args,位于返回地址的上方。请注意在设置了传统堆栈框架后对[ebp+8]和[ebp+12]的访问。
您不需要在asm中声明args;这是一个高级别的概念,您可以在asm中实现自己的代码。
push操作于调用堆栈,而不是堆栈数据结构。https://felixcloutier.com/x86/PUSH.html。它只是减少电除尘器,并存储到[esp]。它这样做是为了保存/恢复调用者的EBP,作为创建传统堆栈框架的一部分。这是非常基本的东西,如果你还没看过,请阅读更多的教程或指南。
您可以很容易地尝试代码并通过从C程序调用它来找到它所做的事情。
但你不能因为你的asm不能组装。.bits 32不是一个有效的GAS指令,但这显然是GNU (GAS)的语法。我不知道除了GAS本身和clang的内置汇编程序之外,没有任何汇编程序有.intel_syntax noprefix指令,而且它们都不支持.bits 32。因此,我猜想这个函数来自于一个教程或者什么的,并且是手工移植到NASM语法(bits 32)或者其他什么东西上,而没有进行实际的测试。但是你不需要,也不应该使用那个指令,或者气体等效的.code32。在将32位代码组装为32位对象文件时,32位代码已经是默认的,因此,如果您只使用没有.code32的gcc foo.s,则可以将32位代码组装成64位的对象文件,然后就会遇到运行时难以调试的问题,而不是在组装时出现明显的错误。
因此,删除.bits 32 行,以解决问题中的错误消息。
为了消除警告消息,通过提供适当的标题和原型,扩展我在评论中写的一行代码。
#include <stdio.h>
int asm0(int,int);
int main(){
printf("%d\n", asm0(123,456));
}这个函数也有问题:它破坏了ebx,这是i386 System调用约定中的一个呼叫保存寄存器。(就像所有正常的x86调用约定一样。)
gcc在Linux发行版上启用默认饼,生成依赖于EBX的代码被调用保护,并且实际上崩溃了。(不过,您仍然可以使用调试器单步执行,因为崩溃发生在asm0返回之后。)
但是,您可以创建一个碰巧工作的可执行文件,并允许您运行它来查看它返回的是哪个arg:
peter@volta:/tmp$ gcc -g -Og -no-pie -fno-pie -m32 main.c asm0.s
peter@volta:/tmp$ ./a.out
456asm0 返回它的第二个arg (通过将它复制到EAX,返回值寄存器)。它将其加载到EBX,然后将EBX复制到EAX,覆盖加载第一个arg.的结果。
您可以在gdb ./a.out中看到这种情况。
(gdb) layout reg
b main
r
si
(press return to single-step one instruction at a time through the code, including into your function)GDB突出显示在每一步中更改了哪些寄存器。
有关更多调试技巧,请参见https://stackoverflow.com/tags/x86/info的底部。
进一步读:
https://stackoverflow.com/questions/52674400
复制相似问题