如何将汇编代码与 C 文件链接,其唯一目的是在汇编代码中调用 C 函数?之后链接仅运行 C 代码

问题描述 投票:0回答:1

我正在做一个项目来学习汇编代码如何集成到编程语言中,以便我可以在处理大型项目时深入理解机器代码抽象。 我使用 VScode 进行编辑,但使用带有开发人员命令行的 MSVC 工具将每个文件编译为 .obj 文件。我的程序集应该打印“选择菜单选项”,然后在执行时打印 4 个菜单项以进行控制台,但目前仅在链接它们后在我的 C 文件中打印测试字符串。

编译main.asm:[ ml /c main.asm ] 编译 procedure.c: [ cl /c procedure.c ]

链接文件: [ link main.obj procedure.obj /OUT:spectra.exe /SUBSYSTEM:CONSOLE /ENTRY:central /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio�2\BuildTools\VC\Tools \MSVC .42.34433\lib\x86" ucrt.lib libcmtd.lib /NODEFAULTLIB:LIBCMT ]

main.asm:

.model flat, stdcall

    EXTERN sayHello: PROC

    .data
        ; Menu strings
       menu_msg DB "Select a menu option 1 - 4:$"

    .code
    central PROC near stdcall
        ; Print menu options
        lea dx, menu_msg         ; Load address of menu message
        mov ah, 09h              ; DOS interrupt for printing strings
        int 21h 
    
        call sayHello

    central ENDP

    END

程序.c:

#include <stdio.h>
    #include <math.h>


    /* Testing & Debugging Functions */
    __declspec(dllexport) void sayHello() {
        printf("Hello from C!\n");
    }

我尝试以 10 种不同的方式链接它们,从指定 /SUBSYSTEM 到 /ENTRY 到指定 MSVC 文件夹中的确切库,它只执行我显式放入 C 文件中的代码,从不运行汇编文件中的任何内容。我该怎么做才能执行汇编代码并将消息打印到控制台?

更新:我试图让 16 位程序集在 64 位 Windows 的终端中运行。我有一些更新的代码,在链接后我终于能够从终端运行,但我无法专门从控制台打印。 C 文件保持不变,但我的程序集已更新,可以打开消息框并显示到目前为止的文本。

编译程序集 = [ ml64 /c /Fo main2.obj main2.asm ] 编译 C 代码 = [ cl /c procedure.c /Fo:procedures.obj ] 链接文件: [ link /OUT:spectra.exe main2.obj procedure.obj /SUBSYSTEM:CONSOLE /ENTRY:main /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio�2\Community\VC\Tools\ MSVC .42.34433\lib\x64" user32.lib libucrt.lib libvcruntime.lib ]

; main2.asm (for 64-bit)

option casemap:none

EXTERN MessageBoxA: PROC
EXTERN ExitProcess: PROC
EXTERN sayHello: PROC

.data
    menu_msg db "Select a menu option:", 0  ; Title of the message box
    option1 db "1. Add two numbers", 0
    option2 db "2. Subtract two numbers", 0
    option3 db "3. Multiply two numbers", 0
    option4 db "4. Divide two numbers", 0

    ; Combine the menu options in the message body
    combined_msg db "1. Add two numbers", 0, "2. Subtract two numbers", 0
    msg_line2 db "3. Multiply two numbers", 0, "4. Divide two numbers", 0

.code
main PROC
    ; Align the stack to 16-byte boundary
    sub rsp, 8                      ; Adjust stack for 16-byte alignment

    ; Call MessageBoxA with the new title and combined message
    mov rcx, 0                      ; uType (0 = OK button)
    lea rdx, option1                ; lpCaption (title of the message box)
    lea r8, menu_msg                ; lpText (message with menu options)
    mov r9, 0                       ; hWnd (no parent window)
    call MessageBoxA                ; Call MessageBoxA API

    ; Add another message box with second part if needed
    lea r8, msg_line2               ; Update text to the next part
    call MessageBoxA                ; Call MessageBoxA API again

    ; Call sayHello procedure (assuming sayHello is implemented in C)
    call sayHello

    ; Exit the program
    mov rcx, 0                      ; Exit code (0)
    call ExitProcess                ; Call ExitProcess API

    ; Clean up the stack
    add rsp, 8                      ; Restore stack

main ENDP

END
c assembly visual-c++ x86-16
1个回答
0
投票

@PeterCordes 解决了:“好吧,那就是你的问题了。编写 64 位代码,不要使用任何 int 指令。int 21h 是 DOS,其他 int 数字大多是 BIOS。int 80h 是 Linux 的 32 位系统 -调用接口,您不想在 64 位代码中使用它,即使在 Linux 上您也不想使用 Windows 没有的系统调用;稳定/记录的系统调用 ABI;而是通过 DLL 进行调用,因此,如果您看到显示 int 或系统调用的示例,那么它们不适用于 x64 Windows(或者它们是关于对 DLL 的系统调用 ABI 进行逆向工程等低级有趣的内容)。使用),寻找不同的教程。”

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.