当前位置:首页 » 编程软件 » 内联汇编编译

内联汇编编译

发布时间: 2022-11-12 03:37:16

1. 内联汇编的GNU 汇编程序简述

linux 中使用的基本汇编程序语法。GCC(用于 Linux 的 GNU C 编译器)使用 AT&T 汇编语法。下面列出了这种语法的一些基本规则。 asm ( assembler template
: output operands (optional)
: input operands (optional)
: list of clobbered registers
(optional)
);
本例中,汇编程序模板由汇编指令组成。输入操作数是充当指令输入操作数使用的 C 表达式。输出操作数是将对其执行汇编指令输出的 C 表达式。
内联汇编的重要性体现在它能够灵活操作,而且可以使其输出通过 C 变量显示出来。因为它具有这种能力,所以 asm 可以用作汇编指令和包含它的 C 程序之间的接口。
一个非常基本但很重要的区别在于 简单内联汇编只包括指令,而 扩展内联汇编包括操作数。要说明这一点,考虑以下示例: { int a=10, b; asm (movl %1, %%eax; movl %%eax, %0; :=r(b) /* output */ :r(a) /* input */ :%eax); /* clobbered register */}
在上例中,我们使用汇编指令使 b 的值等于 a。请注意以下几点:
b 是输出操作数,由 %0 引用,a 是输入操作数,由 %1 引用。 r 是操作数的约束,它指定将变量 a 和 b 存储在寄存器中。请注意,输出操作数约束应该带有一个约束修饰符 =,指定它是输出操作数。 要在 asm 内使用寄存器 %eax,%eax 的前面应该再加一个 %,换句话说就是 %%eax,因为 asm 使用 %0、%1 等来标识变量。任何带有一个 % 的数都看作是输入/输出操作数,而不认为是寄存器。 第三个冒号后的修饰寄存器 %eax 告诉将在 asm 中修改 GCC %eax 的值,这样 GCC 就不使用该寄存器存储任何其它的值。 movl %1, %%eax 将 a 的值移到 %eax 中, movl %%eax, %0 将 %eax 的内容移到 b 中。 因为 b 被指定成输出操作数,因此当 asm 的执行完成后,它将反映出更新的值。换句话说,对 asm 内 b 所做的更改将在 asm 外反映出来。

2. 为什么内联汇编不把字符串名当作指针看待

不可能当指针看的,传递a的指针,当然用lea命令。

3. 请教C++中编译64位程序的时候能否使用32位内联汇编

从x64的设计来说,64-bit模式下是可以使用32-bit指令和大部分16-bit指令的(有一部分16-bit指令的编码被重用了,所以不能用,还有一部分涉及段操作的也不能用),但是在long mode下运行的32-bit(兼容模式)代码是不能使用64-bit指令和新寄存器的。
至于编译器能否使用内嵌汇编,要看设计,cl64就彻底不允许任何嵌入汇编,但是icc、gcc是允许的。

4. gcc内联汇编问题

简单的说吧,"r"表示使用寄存器输入value,即将value的值复制给某一寄存器;而“=r”表示使用寄存器输出到value,即将某一寄存器的值赋给变量value。我没有接触过arm汇编,所以后面那个问题回答不了,抱歉。

5. codeblocks 如何编译16位内联汇编

class MyTest_Base
{
public:
MyTest_Base (int& status)
{
//do other job
// 由于资源不够,对象构建失败
// 把status置0,通知对象的构建者
status = 0;
}
};
void main()
{
int status;
MyTest_Base obj1(status);
// 检查对象的构建是否成功
if(status ==0)
cout << "对象构建失败" << endl;
}

程序运行的结果是:
对象构建失败

在来看下面的程序:
class MyTest_Base
{
public:
MyTest_Base (int& status)
{
//do other job
// 由于资源不够,对象构建失败
// 把status置0,通知对象的构建者
status = 0;
}
virtual ~ MyTest_Base ()
{
cout << "销毁一个MyTest_Base类型的对象" << endl;
}
};
void main()
{
int status;
MyTest_Base obj1(status);
// 检查对象的构建是否成功
if(status ==0)
cout << "对象构建失败" << endl;
}

6. VC6,内联汇编怎么样独立编译并运行的方法

VC可以在CPP文件中嵌入汇编码,但不能编译.asm文件。
可以用masm编译,然后同cpp编译的obj文件连接在一起。而且可以把这个步骤自动化,选择“工程”->"设置"->"Pre Link步骤",把编译.asm成.obj 的命令加进去,就可以啦^ ^

7. 如何在C/C++使用内联汇编

以下所说嵌入的汇编都是GUN 的C语言中嵌入ARM汇编。 1)2个参数的内嵌语句 这种形式的汇编用于简单的语句,参数限制输入和输出语法格式如下: asm(code : output operand list : inputoperand list : clobber list); 汇编和C语句这间的联系是通过上面asm声明中可选的output operand list和input operand list。Clobber list后面再讲。 下面是将C语言的一个整型变量传递给汇编,逻辑左移一位后在传递给C语言的另外一个整型变量。 /* Rotating bits example */ asm("mov %[result], %[value], ror#1" : [result] "=r" (y) : [value] "r" (x)); 每一个asm语句被冒号(:)分成了四个部分。          汇编指令放在第一部分中的“”中间。  "mov %[result], %[value], ror #1"          接下来是冒号后的可选择的output operand list,每一个条目是由一对[](方括号)和被他包括的符号名组成,它后面跟着限制性字符串,再后面是圆括号和它括着的C变量。这个例子中只有一个条目。  [result] "=r" (y)          接着冒号后面是输入操作符列表,它的语法和输入操作列表一样 [value] "r" (x) 为了增加代码的可读性,你可以使用换行,空格,还有C风格的注释。 asm("mov %[result], %[value], ror#1"           : [result]"=r" (y) /* Rotation result. */           : [value]"r" (x) /* Rotated value. */           : /* No clobbers */ ); 在代码部分%后面跟着的是后面两个部分方括号中的符号,它指的是相同符号操作列表中的一个条目。 %[result]表示第二部分的C变量y,%[value]表示三部分的C变量x; 符号操作符的名字使用了独立的命名空间。这就意味着它使用的是其他的符号表。简单一点就是说你不必关心使用的符号名在C代码中已经使用了。在早期的C代码中,循环移位的例子必须要这么写: asm("mov %0, %1, ror #1" :"=r" (result) : "r" (value)) 在汇编代码中操作数的引用使用的是%后面跟一个数字,%1代表第一个操作数,%2代码第二个操作数,往后的类推。这个方法目前最新的编译器还是支持的。但是它不便于维护代码 实例代码: 2) 带.s文件的汇编 编译命令: arm-linux-gcc  main.c Asmfile_gnu.s  -o mains main.c #include extern voidpcm8_2_pcm16(unsigned char* pIn, int nInlen, short* pOut); extern voidpcm16_2_pcm8(short* pIn, int nInlen,unsigned char* pOut); int main() {             unsigned char* pIn="1234";        short pInd[256];        unsigned char pOutd[256];        int nInlen=4;        int i = 0;        short pOut[256];        for(i=0;i<4;i++)                printf(" 0x%x  ",pIn[i]);        printf("\n");        memset((char *)pOut,0,256*2);        memset((char *)pInd,0,256*2);          memset((char *)pOutd,0,256*2);          pcm8_2_pcm16(pIn,nInlen,pOut);        for(i=0;i<4;i++)                printf(" 0x%x  ",pOut[i]);        printf("\n");        memcpy((char *)pInd,(char *)pOut,256*2);        pcm16_2_pcm8(pInd,nInlen,pOutd);        for(i=0;i<4;i++)                printf(" 0x%x  ",pOutd[i]);        printf("\n");          return 0; }   Asmfile_gnu.s .text .global pcm8_2_pcm16 .global pcm16_2_pcm8 #*******************************#  #********* ENCODER 实现将第一个输入参数  #左移8位然后异或0x8000 然后拷贝到第三个参数  #DECODE 取第一个参数所指的数据先异或0x8000  #然后右移8位将数据拷贝到第三个参数  #******************************* pcm8_2_pcm16:        MOV R6,#0        MOV R7,#0 ENCODER:        LDRB R5,[R0,R6]        MOV  R8,R5,LSL#8        EOR  R9,R8,#0x8000       STRH R9,[R2,R7]        ADD  R7,R7,#2        ADD  R6,R6,#1       SUB  R1,R1,#1       CMP  R1,#0       BNE  ENCODER       B    OVER   pcm16_2_pcm8:        MOV  R6,#0        MOV  R7,#0 DECODE:        LDRH R5,[R0,R6]        EOR  R8,R5,#0x8000       MOV  R9,R8,LSR#8       STRB R9,[R2,R7]        ADD  R7,R7,#1        ADD  R6,R6,#2       SUB  R1,R1,#1       CMP  R1,#0       BNE  DECODE OVER:       .en

8. gcc 内联汇编

如下,不懂VC下汇编的规则,不知道那个RADIX是怎么和函数名联系起来的,我就直接用数字3了。加了一些注释方便你读,另外,在具体运算的汇编前后,我加了连续的三个nop空指令方便你反汇编或者debug的时候看到底哪些是通过内联汇编生成的指令,哪些是编译器自己产生的。你可以自行去掉。

unsigned int Div_3(unsigned long long x, unsigned long long *pRemainder)
{
register void * x_addr asm ("ecx") = &x;

asm volatile("nop;nop;nop");
asm volatile ("movl (%%ecx), %%eax\n\t" /* low 32bit of x to eax */
"movl 4(%%ecx), %%edx\n\t" /* high 32bit to edx */
"movl $3, %%ebx\n\t" /* radix = 3 */
"div %%ebx\n\t"
"movl $0, 4(%1)\n\t" /* high 32bit of remainder is 0 */
"movl %%edx, (%1)\n\t" /* remainder */
: /* no output operands */
: "r" (x_addr), "r" (pRemainder)
: "eax", "ebx", "edx");
asm volatile("nop;nop;nop");
}

9. 刚接触内联汇编,下面哪里出错了。。。为什么都可以运行。。。可以详细的跟我讲一下吗

没有出错,确实都能运行,是gcc的编译处理太智能了,理由如下:

①gcc的内联汇编的约束是个很智能的有限约束,能从约束里知道你想怎么写:如代码中的“:"=a"(rrr),:"a"(ccc)”就已经告诉了编译器,要让这段内联汇编代码的效果是“rrr=ccc;”,但是要根据上面的汇编代码写。

②因此,以上asm语句中的内联汇编代码,基本可以随便写。如:

⑴最简单的什么都不写(调试前把汇编代码全部注释掉)如图1

所以说,如果需要ebx干预结果,只能把约束拿掉。至于,都可以运行,那完全是gcc编译器的功劳

10. 内联汇编的介绍

内联汇编,指在C语言中插入汇编语言,其是Linux中使用的基本汇编程序语法。

热点内容
安卓编译打包 发布:2025-07-15 04:24:20 浏览:167
bat编译器 发布:2025-07-15 04:18:07 浏览:54
中兴服务器登录地址 发布:2025-07-15 04:02:47 浏览:988
手提箱怎么改密码 发布:2025-07-15 03:55:47 浏览:219
did脚本 发布:2025-07-15 03:55:12 浏览:963
残留溶剂线性浓度如何配置 发布:2025-07-15 03:54:31 浏览:134
部落冲突好号密码是什么 发布:2025-07-15 03:48:45 浏览:971
存储气瓶 发布:2025-07-15 03:48:10 浏览:992
数据解锁密码有什么用 发布:2025-07-15 03:35:27 浏览:196
腾讯公认的密码是多少 发布:2025-07-15 03:34:44 浏览:626