我的 gcc:线程模型: posix
gcc 版本 8.1.0(x86_64-posix-seh-rev0,由 MinGW-W64 项目构建)
我正在尝试创建一个简单的应用程序,它使用 gcc 和 intel 语法对两个文件 saberi.c 和 saberi.s 的两个数字求和,其中 saberi 表示求和。
萨伯里.c
#include <stdio.h>
int saberi(int a, int b);
int main()
{
int a, b;
scanf("%d %d", &a, &b);
printf("Sum is: %d\n", saberi(a, b));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
军刀
.intel_syntax noprefix
.text
.globl saberi
saberi:
enter 0,0
mov eax, edi
add eax, esi
leave
ret
Run Code Online (Sandbox Code Playgroud)
然后我执行 gcc saberi.c saberi.s ,当我打开可执行文件并输入任意两个数字(例如 1 和 2)时,我会得到一个随机值作为总和。
我有一个关于 ARM 64 寄存器的问题。\n X0代表function argument passing和function return value。是X30. function return address\n 有两个代码片段:
一个是cpp:
\n\nvoid test(void* arg) {}\nRun Code Online (Sandbox Code Playgroud)\n\n另一个是汇编代码:
\n\nmov x3 ,x4\n......\nret \nRun Code Online (Sandbox Code Playgroud)\n\n现在我假设X30存储函数的地址test 并存X0储值0xfffffff
当执行完ret指令后,pc会取出 的值,X30即 的地址test。所以程序将运行到函数test。 \n我的问题是 的值是否arg将被设置为0xffffff,如果不是,我如何将值从我的汇编代码传递到arm 64平台中的函数test\xe2\x80\x99参数?arg
谢谢大家。
\n我对组装非常陌生,所以请耐心等待。
我有这段代码,它通过引用函数传递值以对其进行修改:
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
static void Main()
{
int a = 5 ;
Modify(ref a);
Console.WriteLine(a);
}
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
static void Modify (ref int a )
{
a = 77 ;
}
Run Code Online (Sandbox Code Playgroud)
该代码生成的程序集是
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
static void Main()
{
int a = 5 ;
Modify(ref a);
Console.WriteLine(a);
}
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
static void Modify (ref int a )
{
a = 77 ;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:在指令 L0006 : mov [ebp-4], eax 中,这会将寄存器 eax 的值复制到 Ebp-4 指向的内存位置,但 Ebp-4 没有指向任何内容?我缺少什么?
据我所知,调用约定取决于平台是Windows还是Linux。
我想知道,
哪一个是真的?如果只有 2 为真,则调用约定是由平台定义的,编译器是否只遵循定义的约定?
因此,我一直在练习使用 CDECL 和 STDCALL 调用约定在 FASMW 中编写简单的子例程,这让我想知道printfC 中的函数将使用什么。
此外,x86 32 位汇编中的函数定义也很棒。如果这还不算过分的话。
我正在尝试使用 Win32 API 和 x64 程序集显示打开的文件对话框。为此,我将预期结构的内存分配与结构的内存分配OPENFILENAMEA(在commdlg.h)中进行匹配,但我似乎偏离了 4 个字节,因为我的结构的大小是 140 字节。如果我手动将参数设置为 136 或 152,该CommDlgExtendedError()函数不会返回(0x0001) ,而是会出现“访问冲突读取位置 0x0000010000007FF7”错误。CDERR_STRUCTSIZElStructSize
我ml64.exe在 Visual Studio 2022 Community 中使用 MASM ( ) 并在 x64 下进行组装。
lpEditInfo这是我试图匹配(并被lpstrPrompt省略)的结构: https://learn.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamea
typedef struct tagOFNA {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCSTR lpstrFilter;
LPSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPSTR lpstrFile;
DWORD nMaxFile;
LPSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCSTR lpstrInitialDir;
LPCSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCSTR lpstrDefExt; …Run Code Online (Sandbox Code Playgroud) 这个C++函数的VB6声明是什么?
LPCWSTR* MW_ListReaders(_ULONG Context, int* NumberOfReaders);
Run Code Online (Sandbox Code Playgroud)
以下给了我"糟糕的DLL调用约定":
Private Declare Function ListReaders Lib "MyDLL.dll" (ByVal Context As Long, _
ByRef NumberOfReaders As Integer) As Long
Run Code Online (Sandbox Code Playgroud) import java.util.*;
import java.io.*;
public class Test extends ArrayList
{
ArrayList<String> list = new ArrayList<String>();
public static void main(String[] args)
{
new Test().add();
new Test().contains();
}
public boolean add(){
list.add("cat");
System.out.println(list);
return true;
}
public void contains(){
if (list.contains("cat")){
System.out.println("list contains cat");
}
else{
System.out.println("list doesn't contain cat");
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么结果[cat]列表不包含cat?它一直给我[猫]列表不包含猫.第一种方法是正常工作,但为什么不是第二种方法呢?谢谢......我真的很陌生.
我写了这个小函数:
int mayor(int n1, int n2, int n3, int n4, int n5) {
int mayor = n1;
for(int *p=&n2; p<=&n5; ++p)
mayor = *p;
return mayor;
}
Run Code Online (Sandbox Code Playgroud)
能够保证所有包含该内存块n1到n5是连续的?既然我得到了预期的回报值,我希望如此,但我想知道这是否安全.
c parameter-passing calling-convention memory-layout contiguous
为什么32位C将所有函数参数直接推送到堆栈上,而64位C将前6个参数放入寄存器而其余的放在堆栈中?
所以32位堆栈看起来像:
...
arg2
arg1
return address
old %rbp
Run Code Online (Sandbox Code Playgroud)
虽然64位堆栈看起来像:
...
arg8
arg7
return address
old %rbp
arg6
arg5
arg4
arg3
arg2
arg1
Run Code Online (Sandbox Code Playgroud)
那么为什么64位C会这样做呢?将所有内容都推送到堆栈而不是将前6个参数放在寄存器中以便将它们移动到函数序言中的堆栈中是不是更容易?