将内联英特尔ASM转换为AT&;带GCC扩展ASM的T ASM
在过去的两天里,我一直在学习AT&T内联汇编,但在转换此汇编时遇到了一些问题:将内联英特尔ASM转换为AT&;带GCC扩展ASM的T ASM,gcc,assembly,x86,inline-assembly,Gcc,Assembly,X86,Inline Assembly,在过去的两天里,我一直在学习AT&T内联汇编,但在转换此汇编时遇到了一些问题: 静态字符供应商名称[50]={0}; _asm{ mov-eax,0 cpuid mov dword ptr[卖方名称],ebx mov dword ptr[vendername+4],edx mov dword ptr[vendername+8],ecx } 以下是我的尝试: 静态字符供应商名称[50]={0}; __asm__( movl$0,%%eax\n “cpuid\n” “movl%%ebx,%[ven
静态字符供应商名称[50]={0};
_asm{
mov-eax,0
cpuid
mov dword ptr[卖方名称],ebx
mov dword ptr[vendername+4],edx
mov dword ptr[vendername+8],ecx
}
以下是我的尝试:
静态字符供应商名称[50]={0};
__asm__(
movl$0,%%eax\n
“cpuid\n”
“movl%%ebx,%[vendername]\n”
“movl%%edx,%[vendername+$4]\n”
“movl%%ecx,%[vendername+$8]\n”
:“=r”(供应商名称)//用户供应商名称作为输出
:[vendername]“m”(vendername)//使用vendername作为输入
:“eax”、“ebx”、“edx”、“ecx”//clobbers这些注册表
);
此代码不起作用,gcc给我以下错误:
错误:未定义的命名操作数'vendername+4'
及
错误:未定义的命名操作数'vendername+8'
如何将代码从Intel assembly转换为AT&T assembly?经验法则是,如果您曾经在内联asm中编写
mov
,则可能是做错了:)
编译器可以自己为您加载/存储值,即
int dummy;
union {
char text[12];
struct {
int ebx;
int edx;
int ecx;
};
} vendorname;
__asm__(
"cpuid \n"
: "=b" (vendorname.ebx), "=d" (vendorname.edx), "=c" (vendorname.ecx), "=a" (dummy)
: "a" (0)
);
请注意,由于必须将3个DWORD解释为一个字符串,情况变得复杂。经验法则是,如果您曾经在内联asm中编写
mov
,那么您可能是做错了:)
编译器可以自己为您加载/存储值,即
int dummy;
union {
char text[12];
struct {
int ebx;
int edx;
int ecx;
};
} vendorname;
__asm__(
"cpuid \n"
: "=b" (vendorname.ebx), "=d" (vendorname.edx), "=c" (vendorname.ecx), "=a" (dummy)
: "a" (0)
);
请注意,由于必须将3个DWORD解释为一个字符串,因此情况变得复杂。您可以按以下方式执行:
#include <stdio.h>
int main(int argc, char **argv) {
static char vendername[50] = {0};
__asm__ __volatile__ (
"movl $0, %%eax\n"
"cpuid\n"
"movl %%ebx, %0\n"
"movl %%edx, %0 + 4\n"
"movl %%ecx, %0 + 8\n"
:"=m"(vendername)
:
:"eax", "ebx", "edx", "ecx"
);
printf("%s\n", vendername);
return 0;
}
#包括
int main(int argc,字符**argv){
静态字符供应商名称[50]={0};
__asm\uuuuuu挥发性(
movl$0,%%eax\n
“cpuid\n”
movl%%ebx,%0\n
movl%%edx,%0+4\n
movl%%ecx,%0+8\n
:“=m”(卖方名称)
:
:“eax”、“ebx”、“edx”、“ecx”
);
printf(“%s\n”,供应商名称);
返回0;
}
您可以通过以下方式进行操作:
#include <stdio.h>
int main(int argc, char **argv) {
static char vendername[50] = {0};
__asm__ __volatile__ (
"movl $0, %%eax\n"
"cpuid\n"
"movl %%ebx, %0\n"
"movl %%edx, %0 + 4\n"
"movl %%ecx, %0 + 8\n"
:"=m"(vendername)
:
:"eax", "ebx", "edx", "ecx"
);
printf("%s\n", vendername);
return 0;
}
#包括
int main(int argc,字符**argv){
静态字符供应商名称[50]={0};
__asm\uuuuuu挥发性(
movl$0,%%eax\n
“cpuid\n”
movl%%ebx,%0\n
movl%%edx,%0+4\n
movl%%ecx,%0+8\n
:“=m”(卖方名称)
:
:“eax”、“ebx”、“edx”、“ecx”
);
printf(“%s\n”,供应商名称);
返回0;
}
您需要使用asm\uuuuuuuuuuuuuuuuuuuuuuu volatile\uuuuuuuuuuuuuu
来确保优化器不会删除对CPUID
的调用。您不需要内联asm。MSVC和GNU编译器已经有了内置/包装器。您需要使用\u asm\u\u volatile\u
来确保优化器不会删除对CPUID
的调用。您不需要内联asm。MSVC和GNU编译器已经有了内置/包装器。您确定这是正确的吗:“如果您曾经在内联asm中编写mov,那么您可能是做错了”。我只能得到一些ASM代码的工作,如果它不是扩展的ASM。在没有扩展ASM的情况下,您似乎需要使用mov
。当然,我指的是扩展ASM,它应该保持较小,大多数情况下可以使用输入/输出机制来描述,因此编译器在代码生成方面具有灵活性,而不是可能根本不需要的程序员硬编码mov
。啊,谢谢对于这些基本问题,我很抱歉。我是一个有编程背景的安全人员,但我在这些领域缺乏专业知识。你确定这是正确的吗:“如果你曾经在内联asm中编写mov,那么你可能是做错了”。我只能得到一些ASM代码的工作,如果它不是扩展的ASM。在没有扩展ASM的情况下,您似乎需要使用mov
。当然,我指的是扩展ASM,它应该保持较小,大多数情况下可以使用输入/输出机制来描述,因此编译器在代码生成方面具有灵活性,而不是可能根本不需要的程序员硬编码mov
。啊,谢谢对于这些基本问题,我很抱歉。我是一个有编程背景的安全人员,但我缺乏这些领域的专业知识。