用VC写Assembly代码(7)--在Visual C++中使用内联汇编

C语言ASM(GCC Inline ASM)汇编内嵌语法 带有C/C++表达式的内联汇编GCC允许你通过C/C++表达式指定内联汇编中"Instrcuction List"中指令的输入和输出,你甚至可以不关心到底使用哪个寄存器被使用,完全靠GCC来安排和指定。这一点可以让程序员避免去考虑有限的寄存器的使用,也可以提高目标代码的效率。 阅读详情

 在Visual C++中使用内联汇编

    一、 优点

    使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令,而且不需要额外的汇编和连接步骤。在 Visual C++ 中,内联汇编是内置的编译器,因此不需要配置诸如 MASM 一类的独立汇编工具。这里,我们就以 Visual Studio .NET 2003 为背景,介绍在 Visual C++ 中使用内联汇的相关知识(如果是早期的版本,可能会有些许出入)。

    内联汇编代码可以使用 C/C++ 变量和函数,因此它能非常容易地整合到 C/C++ 代码中。它能做一些对于单独使用 C/C++ 来说非常笨重或不可能完成的任务。

    内联汇编的用途包括:

    * 使用汇编语言编写特定的函数;
    * 编写对速度要求非常较高的代码;
    * 在设备驱动程序中直接访问硬件;
    * 编写 naked 函数的初始化和结束代码。

    二、 关键字

    使用内联汇编要用到 __asm 关键字,它可以出现在任何允许 C/C++ 语句出现的地方。我们来看一些例子:

    * 简单的 __asm 块:

        __asm
        {
            MOV AL, 2
            MOV DX, 0xD007
            OUT AL, DX
        }

    * 在每条汇编指令之前加 __asm 关键字:

        __asm MOV AL, 2
        __asm MOV DX, 0xD007
        __asm OUT AL, DX

    * 因为 __asm 关键字是语句分隔符,所以可以把多条汇编指令放在同一行:

        __asm MOV AL, 2  __asm MOV DX, 0XD007  __asm OUT AL, DX

    显然,第一种方法与 C/C++ 的风格很一致,并且把汇编代码和 C/C++ 代码清楚地分开,还避免了重复输入 __asm 关键字,因此推荐使用第一种方法。

    不像在 C/C++ 中的“{}”,__asm 块的“{}”不会影响 C/C++ 变量的作用范围。同时,__asm 块可以嵌套,而且嵌套也不会影响变量的作用范围。

    为了与低版本的 Visual C++ 兼容,_asm 和 __asm 具有相同的意义。另外,Visual C++ 支持标准 C++ 的 asm 关键字,但是它不会生成任何指令,它的作用仅限于使编译器不会出现编译错误。要使用内联汇编,必须使用 __asm 而不是 asm 关键字。

    三、 汇编语言

1. 指令集

    内联汇编支持 Intel Pentium 4 和 AMD Athlon 的所有指令。更多其它处理器的指令可以通过 _EMIT 伪指令来创建(_EMIT 伪指令说明见下文)。

2. MASM 表达式

    在内联汇编代码中,可以使用所有的 MASM 表达式(MASM 表达式是指用来计算一个数值或一个地址的操作符和操作数的组合)。

3. 数据指示符和操作符

    虽然 __asm 块中允许使用 C/C++ 的数据类型和对象,但它不能使用 MASM 指示符和操作符来定义数据对象。这里特别指出,__asm 块中不允许 MASM 中的定义指示符(DB、DW、DD、DQ、DT 和 DF),也不允许使用 DUP 和 THIS 操作符。MASM 中的结构和记录也不再有效,内联汇编不接受 STRUC、RECORD、WIDTH 或者 MASK。

4. EVEN 和 ALIGN 指示符

    尽管内联汇编不支持大多数 MASM 指示符,但它支持 EVEN 和 ALIGN。当需要的时候,这些指示符在汇编代码里面加入 NOP 指令(空操作)使标号对齐到特定边界。这样可以使某些处理器取指令时具有更高的效率。

5. MASM 宏指示符

    内联汇编不是宏汇编,不能使用 MASM 宏指示符(MACRO、REPT、IRC、IRP 和 ENDM)和宏操作符(<>、!、&、% 和 .TYPE)。

6. 段

    必须使用寄存器而不是名称来指明段(段名称“_TEXT”是无效的)。并且,段跨越必须显式地说明,如 ES:[EBX]。

7. 类型和变量大小

    在内联汇编中,可以用 LENGTH、SIZE 和 TYPE 来获取 C/C++ 变量和类型的大? ?

    * LENGTH 操作符用来取得 C/C++ 中数组的元素个数(如果不是一个数组,则结果为 1)。
    * SIZE 操作符可以获取 C/C++ 变量的大小(一个变量的大小是 LENGTH 和 TYPE 的乘积)。
    * TYPE 操作符可以返回 C/C++ 类型和变量的大小(如果变量是一个数组,它得到的是数组中单个元素的大小)。

    例如,程序中定义了一个 8 维的整数型变量:

        int iArray[8];

    下面是 C 和汇编表达式中得到的 iArray 及其元素的相关值:

        __asm                   C                                   Size

        LENGTH iArray           sizeof(iArray)/sizeof(iArray[0])    8
        SIZE iArray             sizeof(iArray)                      32
        TYPE iArray             sizeof(iArray[0])                   4

8. 注释

    内联汇编中可以使用汇编语言的注释,即“;”。例如:

        __asm MOV EAX, OFFSET pbBuff  ; Load address of pbBuff

    因为 C/C++ 宏将会展开到一个逻辑行中,为了避免在宏中使用汇编语言注释带来的混乱,内联汇编也允许使用 C/C++ 风格的注释。

9. _EMIT 伪指令

    _EMIT 伪指令相当于 MASM 中的 DB,但是 _EMIT 一次只能在当前代码段(.text 段)中定义一个字节。例如:

        __asm
        {
            JMP _CodeLabel

            _EMIT 0x00        ; 定义混合在代码段的数据
            _EMIT 0x01

        _CodeLabel:           ; 这里是代码
            _EMIT 0x90        ; NOP指令
        }

10. 寄存器使用

    一般来说,不能假定某个寄存器在 __asm 块开始的时候有已知的值。寄存器的值将不能保证会从 __asm 块保留到另外一个 __asm 块中。

    如果一个函数声明为 __fastcall 调用方式,则其参数将通过寄存器而不是堆栈来传递。这将会使 __asm 块产生问题,因为函数无法被告知哪个参数在哪个寄存器中。如果函数接收了 EAX 中的参数并立即储存一个值到 EAX 中的话,原来的参数将丢失掉。另外,在所有声明为 __fastcall 的函数中,ECX 寄存器是必须一直保留的。为了避免以上的冲突,包含 __asm 块的函数不要声明为 __fastcall 调用方式。

    * 提示:如果使用 EAX、EBX、ECX、EDX、ESI 和 EDI 寄存器,你不需要保存它。但如果你用到了 DS、SS、SP、BP 和标志寄存器,那就应该用 PUSH 保存这些寄存器。

    * 提示:如果程序中改变了用于 STD 和 CLD 的方向标志,必须将其恢复到原来的值。


四、 使用 C/C++ 元素

1. 可用的 C/C++ 元素

    C/C++ 与汇编语言可以混合使用,在内联汇编中可以使用 C/C++ 变量以及很多其它的 C/C++ 元素,包括:

    * 符号,包括标号、变量和函数名;
    * 常量,包括符号常量和枚举型成员;
    * 宏定义和预处理指示符;
    * 注释,包括“/**/”和“//”;
    * 类型名,包括所有 MASM 中合法的类型;
    * typedef 名称,通常使用 PTR 和 TYPE 操作符,或者使用指定的的结构或枚举成员。

    在内联汇编中,可以使用 C/C++ 或汇编语言的基数计数法。例如,0x100 和 100H 是相等的。

2. 操作符使用

    内联汇编中不能使用诸如“<<”一类的 C/C++ 操作符。但是,C/C++ 和 MASM 共有的操作符(比如“*”和“[]”操作符),都被认为是汇编语言的操作符,是可以使用的。举个例子:

        int iArray[10];

        __asm MOV iArray[6], BX             ; Store BX at iArray + 6 (Not scaled)
        iArray[6] = 0;                      // Store 0 at iArray+12 (Scaled)

    * 提示:在内联汇编中,可以使用 TYPE 操作符使其与 C/C++ 一致。比如,下面两条语句是一样的:

        __asm MOV iArray[6 * TYPE int], 0   ; Store 0 at iArray + 12
        iArray[6] = 0;                      // Store 0 at iArray + 12

3. C/C++ 符号使用

    在 __asm 块中可以引用所有在作用范围内的 C/C++ 符号,包括变量名称、函数名称和标号。但是不能访问 C++ 类的成员函数。

    下面是在内联汇编中使用 C/C++ 符号的一些限制:

    * 每条汇编语句只能包含一个 C/C++ 符号。在一条汇编指令中,多个符号只能出现在 LENGTH、TYPE 或 SIZE 表达式中。
    * 在 __asm 块中引用函数必须先声明。否则,编译器将不能区别 __asm 块中的函数名和标号。
    * 在 __asm 块中不能使用对于 MASM 来说是保留字的 C/C++ 符号(不区分大小写)。MASM 保留字包含指令名称(如 PUSH)和寄存器名称(如 ESI)等。
    * 在 __asm 块中不能识别结构和联合标签。

4. 访问 C/C++ 中的数据

    内联汇编的一个非常大的方便之处是它可以使用名称来引用 C/C++ 变量。例如,如果 C/C++ 变量 iVar 在作用范围内:

        __asm MOV EAX, iVar  ; Stores the value of iVar in EAX

    如果 C/C++ 中的类、结构或者枚举成员具有唯一的名称,则在 __asm 块中可以只通过成员名称来访问(省略“.”操作符之前的变量名或 typedef 名称)。然而,如果成员不是唯一的,你必须在“.”操作符之前加上变量名或 typedef 名称。例如,下面的两个结构都具有 SameName 这个成员变量:

        struct FIRST_TYPE
        {
            char *pszWeasel;
            int SameName;
        };

        struct SECOND_TYPE
        {
            int iWonton;
            long SameName;
        };

    如果按下面方式声明变量:

        struct FIRST_TYPE ftTest;
        struct SECOND_TYPE stTemp;

    那么,所有引用 SameName 成员的地方都必须使用变量名,因为 SameName 不是唯一的。另外,由于上面的 pszWeasel 变量具有唯一的名称,你可以仅仅使用它的成员名称来引用它:

        __asm
        {
            MOV EBX, OFFSET ftTest
            MOV ECX, [EBX]ftTest.SameName       ; 必须使用“ftTest”
            MOV ESI, [EBX]. pszWeasel           ; 可以省略“ftTest”
        }

    * 提示:省略变量名仅仅是为了书写代码方便,生成的汇编指令还是一样的。

5. 用内联汇编写函数

    如果用内联汇编写函数的话,要传递参数和返回一个值都是非常容易的。看下面的例子,比较一下用独立汇编和内联汇编写的函数:

        ; PowerAsm.asm
        ; Compute the power of an integer

        PUBLIC      GetPowerAsm
        _TEXT       SEGMENT WORD PUBLIC 'CODE'
        GetPowerAsm PROC
            PUSH    EBP             ; Save EBP
            MOV     EBP, ESP        ; Move ESP into EBP so we can refer
                                    ; to arguments on the stack
            MOV     EAX, [EBP+4]    ; Get first argument
            MOV     ECX, [EBP+6]    ; Get second argument
            SHL     EAX, CL         ; EAX = EAX * (2 ^ CL)
            POP     EBP             ; Restore EBP
            RET                     ; Return with sum in EAX
        GetPowerAsm ENDP
        _TEXT       ENDS
                    END

    C/C++ 函数一般用堆栈来传递参数,所以上面的函数中需要通过堆栈位置来访问它的参数(在 MASM 或其它一些汇编工具中,也允许通过名称来访问堆栈参数和局部堆栈变量)。

    下面的程序是使用内联汇编写的:

        // PowerC.c

        #include <Stdio.h>

        int GetPowerC(int iNum, int iPower);

        int main()
        {
            printf("3 times 2 to the power of 5 is %d/n", GetPowerC( 3, 5));
        }

        int GetPowerC(int iNum, int iPower)
        {
            __asm
            {
                MOV EAX, iNum   ; Get first argument
                MOV ECX, iPower ; Get second argument
                SHL EAX, CL     ; EAX = EAX * (2 to the power of CL)
            }
            // Return with result in EAX
        }

    使用内联汇编写的 GetPowerC 函数可以通过参数名称来引用它的参数。由于 GetPowerC 函数没有执行 C 的 return 语句,所以编译器会给出一个警告信息,我们可以通过 #pragma warning 禁止生成这个警告。

    内联汇编的其中一个用途是编写 naked 函数的初始化和结束代码。对于一般的函数,编译器会自动帮我们生成函数的初始化(构建参数指针和分配局部变量等)和结束代码(平衡堆栈和返回一个值等)。使用内联汇编,我们可以自己编写干干净净的函数。当然,此时我们必须自己动手做一些有关函数初始化和扫尾的工作。例如:

        void __declspec(naked) MyNakedFunction()
        {
            // Naked functions must provide their own prolog.
            __asm
            {
                PUSH EBP
                MOV ESP, EBP
                SUB ESP, __LOCAL_SIZE
            }

            .
            .
            .

            // And we must provide epilog.
            __asm
            {
                POP EBP
                RET
            }
        }

6. 调用 C/C++ 函数

    内联汇编中调用声明为 __cdecl 方式(默认)的 C/C++ 函数必须由调用者清除参数堆栈,下面是一个调用 C/C++ 函数例子:

        #include <Stdio.h>

        char szFormat[] = "%s %s/n";
        char szHello[] = "Hello";
        char szWorld[] = " world";

        void main()
        {
            __asm
            {
                MOV     EAX, OFFSET szWorld
                PUSH    EAX
                MOV     EAX, OFFSET szHello
                PUSH    EAX
                MOV     EAX, OFFSET szFormat
                PUSH    EAX
                CALL    printf

                // 压入了 3 个参数在堆栈中,调用函数之后要调整堆栈
                ADD     ESP, 12
            }
        }

    * 提示:参数是按从右往左的顺序压入堆栈的。

    如果调用 __stdcall 方式的函数,则不需要自己清除堆栈。因为这种函数的返回指令是 RET n,会自动清除堆栈。大多数 Windows API 函数均为 __stdcall 调用方式(仅除 wsprintf 等几个之外),下面是一个调用 MessageBox 函数的例子:

        #include <Windows.h>

        TCHAR g_tszAppName[] = TEXT("API Test");

        void main()
        {
            TCHAR tszHello[] = TEXT("Hello, world!");

            __asm
            {
                PUSH    MB_OK OR MB_ICONINFORMATION
                PUSH    OFFSET g_tszAppName         ; 全局变量用 OFFSET
                LEA     EAX, tszHello               ; 局部变量用 LEA
                PUSH    EAX
                PUSH    0
                CALL    DWORD PTR [MessageBox]      ; 注意这里不是 CALL MessageBox,而是调用重定位过的函数地址
            }
        }

    * 提示:可以不受限制地访问 C++ 成员变量,但是不能访问 C++ 的成员函数。

7. 定义 __asm 块为 C/C++ 宏

    使用  C/C++ 宏可以方便地把汇编代码插入到源代码中。但是这其中需要额外地注意,因为宏将会扩展到一个逻辑行中。
为了不会出现问题,请按以下规则编写宏:

    * 使用括号把 __asm 块包围住;
    * 把 __asm 关键字放在每条汇编指令之前;
    * 使用经典 C 风格的注释(“/* comment */”),不要使用汇编风格的注释(“; comment”)或单行的 C/C++ 注释(“// comment”);

    举个例子,下面定义了一个简单的宏:

        #define PORTIO __asm        /
        /* Port output */           /
        {                           /
            __asm MOV AL, 2         /
            __asm MOV DX, 0xD007    /
            __asm OUT DX, AL        /
        }

    乍一看来,后面的三个 __asm 关键字好像是多余的。其实它们是需要的,因为宏将被扩展到一个单行中:

        __asm /* Port output */ {__asm MOV AL, 2  __asm MOV DX, 0xD007  __asm OUT DX, AL}

    从扩展后的代码中可以看出,第三个和第四个 __asm 关键字是必须的(作为语句分隔符)。在 __asm 块中,只有 __asm 关键字和换行符会被认为是语句分隔符,又因为定义为宏的一个语句块会被认为是一个逻辑行,所以必须在每条指令之前使用 __asm 关键字。

    括号也是需要的,如果省略了它,编译器将不知道汇编代码在哪里结束,__asm 块后面的 C/C++ 语句看起来会被认为是汇编指令。

    同样是由于宏展开的原因,汇编风格的注释(“; comment”)和单行的 C/C++ 注释(“// commen”)也可能会出现错误。为了避免这些错误,在定义 __asm 块为宏时请使用经典 C 风格的注释(“/* comment */”)。

    和 C/C++ 宏一样 __asm 块写的宏也可以拥有参数。和 C/C++ 宏不一样的是,__asm 宏不能返回一个值,因此,不能使用这种宏作为 C/C++ 表达式。

    不要不加选择地调用这种类型的宏。比如,在声明为 __fastcall 的函数中调用汇编语言宏可能会导致不可预料的结果(请参看前文的说明)。

8. 转跳

    可以在 C/C++ 里面使用 goto 转跳到 __asm 块中的标号处,也可以在 __asm 块中转跳到 __asm 块里面或外面的标号处。__asm 块内的标号是不区分大小写的(指令、指示符等也是不区分大小写的)。例如:

        void MyFunction()
        {
            goto C_Dest;    /* 正确 */
            goto c_dest;    /* 错误 */

            goto A_Dest;    /* 正确 */
            goto a_dest;    /* 正确 */

            __asm
            {
                JMP C_Dest  ; 正确
                JMP c_dest  ; 错误

                JMP A_Dest  ; 正确
                JMP a_dest  ; 正确

        a_dest:             ; __asm 标号
            }

        C_Dest:             /* C/C++ 标号 */
            return;
        }

    不要使用函数名称当作标号,否则将转跳到函数中执行,而不是标号处。例如,由于 exit 是 C/C++ 的函数,下面的转跳将不会到 exit 标号处:

        ; 错误:使用函数名作为标号
        JNE exit
        .
        .
        .
        exit:
        .
        .
        .

    美元符号“$”用于指定当前指令位置,常用于条件跳转中,例如:

        JNE $+5     ; 下面这条指令的长度是 5 个字节
        JMP _Label
        NOP         ; $+5,转跳到了这里
        .
        .
        .
        _Label:
        .
        .
        .

    五、在 Visual C++ 工程中使用独立汇编

    内联汇编代码不易于移植,如果你的程序打算在不同类型的机器(比如 x86 和 Alpha)上运行,你可能需要在不同的模块中使用特定的机器代码。这时候你可以使用 MASM(Microsoft Macro Assembler),因为 MASM 支持更多方便的宏指令和数据指示符。

    这里简单介绍一下在 Visual Studio .NET 2003 中调用 MASM 编译独立汇编文件的步骤。

    在 Visual C++ 工程中,添加按 MASM 的要求编写的 .asm 文件。在解决方案资源管理器中,右击这个文件,选择“属性”菜单项,在属性对话框中,点击“自定义生成步骤”,设置如下项目:

    命令行:ML.exe /nologo /c /coff "-Fo$(IntDir)/$(InputName).obj" "$(InputPath)"
    输出:$(IntDir)/$(InputName).obj

    如果要生成调试信息,可以在命令行中加入“/Zi”参数,还可以根据需要生成 .lst 和 .sbr 文件。

    如果要在汇编文件中调用 Windows API,可以从网上下载 MASM32 包(包含了 MASM 汇编工具、非常完整的 Windows API 头文件/库文件、实用宏以及大量的 Win32 汇编例子等)。相应地,应该在命令行中加入“/I X:/MASM32/INCLUDE”参数指定 Windows API 汇编头文件(.inc)的路径。MASM32 的主页是:http://www.masm32.com,里面可以下载最新版本的 MASM32 包。

gnu嵌入汇编,内嵌汇编详细的介绍 GCC 提供了内嵌汇编的功能,可以在 C 代码中直接内嵌汇编语言语句,大大方便了程序设计。简单的内嵌汇编很容易理解,例: __asm__ __volatile__("hlt"); "__asm__" 表示后面的代码为内嵌汇编,“asm”是“__asm__”的别名。 “__volatile__” 表示编译器不要优化代码,后面的指令保留原样,“volatile”是它的别名。 括号里面是汇编指令。 ... 阅读详情

相关推荐

内嵌汇编

内嵌汇编 操作系统高级教程上面需要阅读Linux内核0.11的源码,其中在书《Linux内核设计的一书》第2.5节异常处理类中段服务程序挂接的部分,遇到了嵌入在C语言中的汇编代码,之前从来没有学习过汇编,因此记录下。 AT&T基础知识 内嵌汇编使用的是AT&T汇编,所以首先稍微讲解下AT&T的汇编指令的基础知识。 操作数前缀 movl $8,%eax movl ...

qq_33620071的博客 2534

[原创]在 Visual C++ 中使用内联汇编

一、 优点    使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令,而且不需要额外的汇编和连接步骤。在 Visual C++ 中,内联汇编是内置的编译器,因此不需要配置诸如 MASM 一类的独立汇编工具。这里,我们就以 Visual Studio .NET 2003 为背景,介绍在 Visual C++ 中使用内联汇的相关知识(如果是早期的版本,可能会有些许出入)。    内联汇编代

Yonsm.NET 2222

2022-2028年中国美容仪行业发展战略规划及投资机会预测报告

报告类型:产业研究 报告格式:电子版、纸介版 出品单位:智研咨询-产业信息网 美容仪是一种根据人体生理机能进行调节改善身体和面部的机器,它按照功能来说有美白、嫩肤、祛斑、祛皱、脱毛、减肥等多种,按照名称来说有超声波导入、光子嫩肤、高周波电疗、RF 电波拉皮、电子祛斑点痣、E 光永久脱毛嫩肤、贾法尼营养导入导出等。 智研咨询发布的《2022-2028年中国美容仪行业发展战略规划及投资机会预测报告》共十七章。首先介绍了中国美容仪行业市场发展环境、美容仪整体运行态势等,接着分析了中...

kt346的博客 468

【C/C++】__asm__关键字

在公司的代码学习中看见这么几行: __asm__( "movl %%esp,%0" :"=r"(myesp)); 查阅资料后得知 C++ asm是一个在C++代码中嵌入汇编指令的关键字 格式如下: asm ("Assembler");//Assenmbler指汇编指令 /* *你会看到“asm”变成了关键字样式的字体 *汇编指令由字符串方式填在括号里 *有的编译器会把嵌入的汇编指令单独放在一个文件里编译 */ //另外插入多条汇编语句: asm( "mov eax,1\n" "leave\n" "

Hello,My Friends~ 4663

从零到一:用Verilog和Quartus构建智能交通灯系统的实战指南

本文详细介绍了如何使用Verilog和Quartus Prime从零开始构建智能交通灯系统。通过分步指导,包括状态机设计、时序控制、数码管显示等核心模块实现,并结合ModelSim仿真验证,帮助FPGA初学者掌握数字电路设计的关键技术。文章还提供了实际部署到FPGA开发板的调试技巧和进阶优化方案。

weixin_29172201的博客 477

ICNN实现入侵检测的思路与源码(CIC-IDS-2017)

基于ICNN实现入侵检测,可用于现实网络

t1274171989的博客 8415

(reship) oracle lock logic

我们知道,数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁。本文我们主要就介绍一下Oracle数据库的悲观锁与乐观锁的相关知识,希望能够对您有所收获! AD:   Oracle数据库悲观锁与乐观锁是本文我们主要要介绍的内容。有时候为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突。为了解决这个问题,大多数数据库用的方法就是数据的锁定。...

echo46219519的专栏 196

ubuntu20.04安装Qt5.15.2并配置环境

qt官方取消了离线安装的方式,所以推荐在线安装,当然,如果想要自己通过源码编译也可以,参考官方文档:https://wiki.qt.io/Building_Qt_5_from_Git。 在线安装: 1.到官方网站下载:wget https://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run 2.修改文件权限:chmod 777 qt-unified-linux-x64-online.run

f120854632的博客 8807

【C++初阶】C++入门

C++入门C++关键字命名空间C++输入&输出缺省参数和函数重载为什么C语言不能重载(原理) C++关键字 1、asm _asm是一个语句的分隔符。不能单独出现,必须接汇编指令。一组被大括号包含的指令或一对空括号。 例: _asm { mov al,2 mov dx,0xD007 out al,dx } 也可以在每个汇编指令前加_asm _asm mov al,2 _asm mov dx,0xD007 _asm out al,dx 2、auto auto关键字会根据初始值自动推断变量的数据类型

Anton的博客 743

Exploring Automated Distractor Generation for Math Multiple-choice Questions via Large Language Mode

多项选择题(MCQ)在几乎所有级别的教育中都无处不在,因为它们易于管理、评分,并且是评估和实践中可靠的格式。MCQ最重要的方面之一是干扰因素,即旨在针对真实学生常见错误或误解的不正确选项。迄今为止,对于教师和学习内容设计师来说,制作高质量的干扰物的任务在很大程度上仍然是一个劳动和时间密集型的过程,其可扩展性有限。在这项工作中,我们研究了数学MCQ领域的自动干扰物生成任务,并探索了从上下文学习到微调的各种基于大型语言模型(LLM)的方法。

c_cpp_csharp的专栏 317

振镜控制卡硬件接口揭秘:XY2-100/SL2-100协议对比

本文对比分析了工业振镜控制领域两种主流数字通信协议XY2-100和SL2-100的硬件接口差异与应用场景。XY2-100作为开放式协议兼容性强,采用LVDS差分信号传输,适用于激光打标等中高精度场景;SL2-100为半封闭协议,采用RS485差分信号,专为高速响应场景设计。文章详细解析了两种协议的引脚定义、通信机制和性能参数,指出XY2-100适配多品牌振镜且调试简单,SL2-100则更适合Nutfield专用设备的高速高精度需求。最后提供了接口调试的实操建议和选型逻辑,强调应根据具体应用场景的精度、速度和

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 651

汇编1

.data hello:.ascii "hello" .text .global _start _start: movl $4,%eax movl $1,%ebx movl $hello,%ecx movl $5,%edx int $0x80 eax:4 ebx:1,write系统调用,1代表STDOUT_FILENO .global _start _start: movl $1,%ea

A1157599735的专栏 7万+

基于互联网的智能旧衣回收箱设计与实现

本文介绍了基于嵌入式系统的智能旧衣回收箱的设计与实现,涵盖了硬件设计、软件开发、图像识别、物联网连接等方面的内容。通过利用最新的技术,如图像识别、物联网和云计算,实现了智能、便捷的旧衣物回收系统。未来,随着技术的不断进步,智能回收系统将会在环保领域发挥更大的作用。

2201_76125393的博客 908

汇编语言-与C++混合编程

1.嵌入汇编 高级语言和汇编语言 给软件开发通常采用高级语言,以提高开发效率 某些部分利用汇编语言,以提高程序的运行效率 ▶汇编语言的优点 开发的程序占用存储空间小、运行速度快 ▶汇编语言的缺点 与处理器密切相关、移植性差,编程烦琐、调试困难 混合编程 汇编语言与高级语言、或不同高级语言间,通过相互调用、参数传递、共享数据结构和数据信息而形成程序的过程,称为“混合编程” 嵌入汇编 嵌入汇编(内嵌汇编、内联汇编、行内汇编) ▶直接在C/C++语言的源程序中插入汇编语言

wmy1819985954的博客 1616

基于深度学习的三维重建算法——详解与实现

随着深度学习技术的迅猛发展,基于深度学习的三维重建算法在最近几年取得了显著的进展。而基于深度学习的三维重建算法通过利用深度神经网络,能够从大规模数据中学习到更准确、鲁棒的三维结构表示。本文综述了基于深度学习的三维重建算法,并给出了相应的源代码。随着深度学习技术的不断发展,我们相信基于深度学习的三维重建算法将会在未来得到更广泛的应用。实验结果表明,基于深度学习的三维重建算法在准确性和鲁棒性方面取得了显著的提升。以上是关于基于深度学习的三维重建算法的详细介绍与实现,希望对您有所帮助。

CyberGenius的博客 1230

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

__asm__ __volatile__内嵌汇编用法简述

 __asm__ __volatile__内嵌汇编用法简述 在阅读C/C++原码时经常会遇到内联汇编的情况,下面简要介绍下__asm__ __volatile__内嵌汇编用法。因为我们华清远见教学平台是ARM体系结构的,所以下面的示例都是用ARM汇编。 带有C/C++表达式的内联汇编格式为: __asm__ __volatile__("Instruction List" : Outpu

lemon_fantasy的专栏 3810

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

AT&T汇编语言与GCC内嵌汇编简介

   1 AT&T 与INTEL的汇编语言语法的区别1.1大小写1.2操作数赋值方向1.3前缀1.4间接寻址语法1.5后缀1.6指令 2 GCC内嵌汇编2.1简介2.2内嵌汇编举例2.3语法2.3.1汇编语句模板2.3.2输出部分2.3.3输入部分2.3.4限制字符2.3.5破坏描述部分2.4GCC如何编译内嵌汇编代码 

界外 3162

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

4.1内联汇编

目前编译器都比较智能,能将 C 代码转换为高效率的汇编指令,但是对于某些特殊指令(如 ldrex 、 strex 实现互斥访问)或特殊算法编译器则无法正常转换,此时则需要使用汇编来实现相应的功能,如果不想创建单独的汇编文件则需要采用在C语言中嵌入汇编指令的方式来实现。

lf282481431的博客 1467

C++11主要新增使用语法介绍

C++11介绍,同一初始化列表,auto,decltype,nullptr 关键字的引入;STL容器的变化;右值引用概念,完美转发;新增默认成员函数,移动构造,移动赋值;可变参数模板概念;lambda匿名函数介绍;包装器概念介绍

blue_jun_的博客 1333

VS嵌入汇编ASM

1.嵌入汇编语言的格式 C++语言是C语言的超集,它是在C语言的基础上扩展形成的面向对象程序设计语言。微软Visual C++ 5.0∕6.0则是Windows 9.x平台上广泛应用的开发系统。本节以Visual C++ 5.0∕6.0为例,说明32位Windows 9.x环境下汇编语言与C++的混合编程。它也分为嵌入汇编和模块调用两种方式。 Visual ...

weixin_34332905的博客 1498

inline asm进阶

1、如何传入一个neon的向量寄存器,并在此寄存器的基础上进行修改?假设传入一个float32x4_t的数据,经过asm处理该数据后返回: float a[4] = { 1.0,2.0,3.0,4.0 }; float32x4_t v_tmp = vdupq_n_f32(100.0); __asm__ volatile( "ld1 {v0.4s},[%[src]] \n" "fadd %[dst].4s, %[dst].4s,v0.4s" :[src]"=r"(a), [dst]"=w"(v_t

azheng_wen的博客 739

C++嵌入汇编demo (_asm用法)

C++嵌入汇编demo

Meta.Qing的博客 1117

C++中使用内联汇编

很多的时候可以采用__asm{}的形式就可以嵌入汇编代码 #include <stdio.h> int power2(int num, int power); void main(void) { printf("%d\n", power2(3,3)); } int power2(int num, int power) { __asm { push eax ...

junehappylove(王俊伟)的专栏 6738

C++中使用汇编

内嵌汇编允许将汇编代码直接嵌入到 C++ 代码中,以实现对底层硬件的直接访问和控制。内嵌汇编使用的是汇编语言的语法和指令集。需要注意的是,内嵌汇编块中的汇编指令通常需要使用特定的语法和约定,以兼容编译器和目标平台。内嵌汇编允许在汇编代码块中使用 C++ 的变量和寄存器。通过使用特殊的语法,可以将 C++ 变量与汇编寄存器进行关联,实现数据的输入和输出。因此,如果你使用的是较新的编译器,应参考特定编译器的文档和指南,以了解正确的语法和约束规则。在 C++ 中使用内嵌汇编时,可以通过将汇编代码放置在。

ultramand的博客,重生之我在cad上二次开发猛猛敲C#代码~ 2979

GCC Inline ASM

GCC Inline ASM GCC has an extremely powerful feature where it allows inline assembly within C (or C++) code. Other assemblers allow verbatim assembly constructs to be inserted into object code. The a

samssm的专栏 4033

volatile、restrict、gcc优化、内嵌汇编的memory修饰符

GCC在C语言中内嵌汇编-转载 http://hi.baidu.com/liu_bin0101/blog/item/433103007852b216738b658d.html 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可, GCC会...

1118
上一篇: 用VC写Assembly代码
下一篇: Why Learning Assembly Language is Still a Good Idea
普通网友
博客等级 码龄22年 1万+粉丝 3156原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值