我想写一个小的低级程序.对于它的某些部分,我将需要使用汇编语言,但其余代码将使用C/C++编写.
那么,如果我使用GCC将C/C++与汇编代码混合在一起,我是否需要使用AT&T语法,还是可以使用Intel语法?或者你如何以其他方式混合使用C/C++和asm(intel语法)?
我意识到也许我没有选择,必须使用AT&T语法,但我想确定..
如果结果没有选择,我可以在哪里找到有关AT&T语法的完整/官方文档?
谢谢!
正如这个问题所示,使用g ++,我能做到g++ -S -masm=intel test.cpp.另外,对于clang,我可以这样做clang++ -S test.cpp,但-masm=intelclang(warning argument unused during compilation: -masm=intel)不支持.如何使用clang获取intel语法?
我想检查boost::variant在我的代码中应用的程序集输出,以便查看哪些中间调用被优化掉了.
当我编译以下示例(使用GCC 5.3 g++ -O3 -std=c++14 -S)时,似乎编译器优化了所有内容并直接返回100:
(...)
main:
.LFB9320:
.cfi_startproc
movl $100, %eax
ret
.cfi_endproc
(...)
Run Code Online (Sandbox Code Playgroud)
#include <boost/variant.hpp>
struct Foo
{
int get() { return 100; }
};
struct Bar
{
int get() { return 999; }
};
using Variant = boost::variant<Foo, Bar>;
int run(Variant v)
{
return boost::apply_visitor([](auto& x){return x.get();}, v);
}
int main()
{
Foo f;
return run(f);
}
Run Code Online (Sandbox Code Playgroud)
但是,完整的程序集输出包含的内容远远超过上面的摘录,对我而言,它看起来永远不会被调用.有没有办法告诉GCC/clang删除所有"噪音"并输出程序运行时实际调用的内容?
完整装配输出:
.file "main1.cpp"
.section .rodata.str1.8,"aMS",@progbits,1
.align 8
.LC0:
.string "/opt/boost/include/boost/variant/detail/forced_return.hpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC1: …Run Code Online (Sandbox Code Playgroud) 是否有一种简单的方法(如免费程序)可以将c/c ++代码转换为x86程序集?
我知道任何c编译器都做了非常类似的事情,我可以编译c代码,然后反汇编编译的可执行文件,但这有点过分,我想要的只是转换几行代码.
有谁知道一些可以做到这一点的程序?
编辑:我知道GCC编译器这样做,但它是AT&T语法,我正在寻找英特尔语法(不确定它是否称为英特尔语法).AT&T语法对我来说有点像胡言乱语,有些命令以相反的顺序使用操作数,而不是我习惯的方式,它可能会让人感到困惑.
我想用gcc编译intel语法汇编.可能吗?因为我找不到类似的东西.我刚发现这篇文章.
这是我试图编译的代码.
global _main
section .text
_main:
mov eax, -1
ret
Run Code Online (Sandbox Code Playgroud)
如果无法做到这一点,请在答案中提供其他选项.
我有一个ARM汇编代码,可以很好地编译Visual Studio.我想现在使用相同的ARM汇编代码并使用GNU Assembler进行编译.如您所知,两个汇编程序的语法都不同.我想知道是否有任何工具可以从这些汇编语法转换.
我发现这段代码将堆栈指针放入EAX寄存器(它应该是C中“return”使用的寄存器)
#include <stdio.h>
unsigned long get_sp(){
unsigned long stp;
__asm{
mov
eax, esp
}
}
void main(void){
printf("\n0x%x", get_sp());
}
Run Code Online (Sandbox Code Playgroud)
我用 Geany 试过了,但它不起作用!!然后我按照编译器日志,以这种方式更改了代码:
#include <stdio.h>
unsigned long get_sp(void);
int main(void){
printf("\n0x%ld", get_sp());
return 0;
}
unsigned long get_sp(void){
unsigned long stp;
__asm{
mov eax, esp
}
}
Run Code Online (Sandbox Code Playgroud)
这次我的主要功能没有问题,但其他功能是悲剧!!!它无法识别 __asm。未知类型名称 'mov'.... 未使用的变量 'eax'... 似乎它想要 __asm() 而不是 __asm{},就像正常调用函数一样。有人可以帮助我吗?PS 我有 debian 64 ......它可能在 64 架构上有一些问题??
我有以下代码,可以用 gcc 命令很好地编译gcc ./example.c。程序本身调用函数“add_two”,它只是将两个整数相加。要在扩展汇编指令中使用 intel 语法,我需要首先切换到 intel,然后再切换回 AT&T。根据 gcc 文档,可以使用gcc -masm=intel ./exmaple.
每当我尝试使用 switch 编译它时,-masm=intel它都不会编译,我不明白为什么?我已经尝试删除该指令,.intel_syntax但它仍然无法编译。
#include <stdio.h>
int add_two(int, int);
int main(){
int src = 3;
int dst = 5;
printf("summe = %d \n", add_two(src, dst));
return 0;
}
int add_two(int src, int dst){
int sum;
asm (
".intel_syntax;" //switch to intel syntax
"mov %0, %1;"
"add %0, %2;"
".att_syntax;" //switch to at&t syntax
: "=r" (sum) //output
: "r" (src), "r" …Run Code Online (Sandbox Code Playgroud) 我有一个简单的内联汇编函数,它在MSVC中工作正常,但由于某种原因拒绝在Apple GCC 4.2.1(i386 arch,强制32位模式)下工作.幸运的是,更复杂的汇编函数工作得很好,但是我无法理解为什么这个函数不能正常工作...不幸的是,我无法调试它 - 看看事情在XCode 4.0.2中没有寄存器窗口(它是3.2版本).
我很肯定这个问题与英特尔风格的装配无关.
int Convert(double value)
{
_asm
{
fld value
push eax
fistp dword ptr [esp]
pop eax
}
// The returned value is insane
}
Run Code Online (Sandbox Code Playgroud) 所以我想出了如何在C语言中反转一个四字节长的int的字节序:
unsigned int swapWord (unsigned int n){
return (n>>24) | ((n<<8) & 0x00FF0000) |((n>>8) & 0x0000FF00) | (n<<24);
}
Run Code Online (Sandbox Code Playgroud)
现在,我知道我可以反汇编它了,而且确实做到了,这是不错的代码,但是我敢肯定,有一种更有效的方法可以逆转固有性。有任何想法吗?
编辑:这是反汇编的代码:
00000000004005a3 <swapWord>:
4005a3: 55 push %rbp
4005a4: 48 89 e5 mov %rsp,%rbp
4005a7: 89 7d fc mov %edi,-0x4(%rbp)
4005aa: 8b 45 fc mov -0x4(%rbp),%eax
4005ad: c1 e8 18 shr $0x18,%eax
4005b0: 89 c2 mov %eax,%edx
4005b2: 8b 45 fc mov -0x4(%rbp),%eax
4005b5: c1 e0 08 shl $0x8,%eax
4005b8: 25 00 00 ff 00 and $0xff0000,%eax
4005bd: 09 c2 or …Run Code Online (Sandbox Code Playgroud)