首页 > 系统相关 >Windows平台NASM汇编与C混合调用

Windows平台NASM汇编与C混合调用

时间:2024-04-28 13:56:03浏览次数:26  
标签:汇编 Windows print NASM hello strhello

Windows平台NASM汇编与C混合调用

tonyblackwhite

之前介绍了Windows平台下,用微软宏汇编MASM与C混合调用的方法。MASM是微软独有的,Linux没法用,我喜欢学一个能够应用于两种平台的,所以还是更钟情于开源的可跨平台的NASM汇编。

tonyblackwhite:Win平台最简单的方式实现C程序调用汇编函数6 赞同 · 0 评论文章

本文介绍Windows平台NASM汇编与C混合调用的方法。

GCC不用多解释,这是大名鼎鼎的C、C++的编译器,简直可以搞一切。

NASM是一个开源的x86的汇编器,用来编译汇编的。

为什么要研究GCC和NASM的联合编译呢?GCC本来就能够嵌套汇编代码啊?这是因为GCC中嵌套的汇编代码是AT&T的汇编代码不是Intel格式的汇编。AT&T汇编我不喜欢用,只喜欢用Intel汇编,也就是类似于MASM和NASM这样子的。

下面我们结合一个例子来将二者如何联合使用。

如果大家善用搜索,就会发现网上有大量的例子,讲述了Linux平台下,GCC和NASM联合调用的例子。

那我还写个什么劲呢?原来,这些例子一旦应用到Windows平台,幺蛾子就来了。

本文就是讲述Windows平台下,GCC和NASM联合调用时如何灭掉那些幺蛾子的。

1、简单例子

该例子包含两个文件:test1.asm和test.c。

test1.asm的内容为

extern _print_helloworld

[section .text]

global _print_two_hello_world

_print_two_hello_world:

call _print_helloworld

call _print_helloworld

test.c的内容为

#include "stdio.h"extern void print_two_hello_world();char *strhello = "Hello,world!\n";

void print_helloworld(){

printf("%s", strhello);}

int main(){

print_two_hello_world();

return 0;}

这里,在NASM汇编程序中,声明了一个全局函数print_two_hello_world,由于这里是Windows平台,该全局函数就变成了_print_two_hello_world函数,即增加了前导的下划线。这与Windows平台的调用方式stdcall有关。

该汇编程序文件还声明外部有一个函数_print_helloworld,这是由C程序提供的,同样也增加了一个前导下划线。

前导下划线使得程序不美观,而且它的加入使得该汇编程序无法应用于Linux平台。后面会讲述解决方法。

这里,只需要记住了,在Win平台下,所有C文件需要用到的函数到了这里都加入了前导下划线。

输入如下编译指令,运行,可得结果:

IMG_257

在这个简单的例子中,C程序调用了NASM中的函数,而NASM汇编中有调用了C中的函数,而且在Windows平台中,这些函数都加入了前导下划线。这是与Linux平台最大的不同。

这个例子就是简单的C与汇编相互调用的例子,好像汇编也没那么难嘛!

2、复杂例子

该例子包含两个文件:test1.asm和test.c。

test1.asm的内容为

global _string

extern _strhello

extern _printf

[section .data]

_string:

db 'I am Chinese.',0x0A,0x0

 

[section .text]

global _print_hello

_print_hello:

push dword [_strhello]

call _printf

add esp,byte 4

ret

test.c的内容为

#include "stdio.h"

#include "string.h"

 

extern char *string;

extern void print_hello();

 

char *strhello = "Hello,world!\n";

char *str = NULL;

 

int main(){

str = &string;

printf("%s", str);

 

print_hello();

return 0;

}

输入如下编译指令,运行,可得结果:

IMG_258

上图中,出现了那句警告!!!

别怕,这句话没有错!在C语言中定义了一个strhello的字符串变量,在C语言中strhello表示的是字符串的首地址,比如字符串的地址是0xa00001,而strhello是个指针即4字节其地址为0xb00001, 在C语言中strhello表示的值是 0xa00001 字符串的首地址,但到了NASM中则表示的 strhello变量的首地址了 0xb00001,所以汇编中用下面这个取出具体内存中的内容:

push dword [_strhello]

代码中加了中括号表示是内容,这一点一定要注意,否则会出错!!

另外,上面汇编中,所有的全局函数、引用函数、引用外部数据等都加了_下划线。显然,这还是Windwos平台的特殊性带来的。

关于win平台下函数和变量增加_下划线的思考:

如果nasm文件中仅仅是一两个函数,那就像我之前做的那样,可以直接在函数前面加下划线,也不是不可以。这主要是Windows的stdcall方式为函数名自动加前导的下划线导致的。

如果是多个文件或者n个函数,这种手动添加前导下划线的方式是不可取的,会增加工作量,而且容易出错,此外还破坏了NASM的平台可移植性,也破坏了NASM程序的美感。

那么怎么解决呢?可以在编译时用–prefix给全局参数或者函数添加前缀,即nasm指令使用时增加如下附加指令:

--prefix _

下面改造例子2:

定义test2.asm的内容为:

global string

extern strhello

extern printf

[section .data]

string:

db 'I am Chinese.',0x0A,0x0

 

[section .text]

global print_hello

print_hello:

push dword [strhello]

call printf

add esp,byte 4

ret

显然,去掉了所有_下划线,现在使用如下指令编译、运行:

IMG_259

你看,在nasm指令中增加一句--prefix _就解决了NASM汇编的可移植性问题。

现在,NASM程序完全具有可移植性了(Linux和Widnows平台通用了),美观度也大大增加了。其实汇编语言也挺好看的,哈哈!

本文就是在Windows平台,如何使用GCC和NASM混合编程的例子。

注意,本文的方法,使得NASM程序真正的跨平台了。

标签:汇编,Windows,print,NASM,hello,strhello
From: https://www.cnblogs.com/djcsch2001/p/18163610

相关文章

  • Windows git绑定GitHub
    1、打开gitBash2、输入ssh-keygen-trsa-C 'GitHub邮箱账号'  // 一直回车3、获取生成秘钥id_rsa.pub从C盘-用户-用户名目录对应的.ssh文件,打开id_rsa.pub文件,复制里面的数据4、将复制的秘钥添加到github上步骤1:点击头像打开settings步骤2:打开页面左边的SSHan......
  • 汇编基础
    CPU结构和指令集CPU是名称为中央处理单元,简称处理器,主要的作用是从内存中读取指令,然后解码和执行。CPU架构就是CPU内部设计的结构,是一堆硬件组成,用于实现指令集所规定的操作指令集包含了一系列的操作码(opcode),以及特定的CPU执行的基本命令。如果想要设计CPU,就得先解决使用什么样......
  • windows系统,大文本文件打开工具
    在Windows系统中,打开大文本文件的工具有多种选择。以下是一些推荐的软件:LogView:这是一款能够快速打开大文件的工具,对于300MB以上的文件,它基本上能在一分钟内打开。虽然打开大文件时可能会占用较多的内存,但它的处理速度相对较快,使得它成为处理大文本文件的理想选择。EditPlus:Edi......
  • 【FileZillaServer用网络驱动器作为主目录时,客户端无法列出文件】【Spring Boot安装成
    遇到的两个问题安装FileZillaServer后,把映射的网络驱动器内容作为主目录时,客户端能正常登录,但是无法列出文件。把本机的某个目录组为主目录,客户端可以正常列出文件。把SpringBoot安装成Windows服务时,访问系统中映射的网络驱动器失败(开发过程中能够正常访问,通过命令的方式......
  • Installation requirements for SAP Kernels on Windows (C++ runtime environment, V
      Symptom在Windows执行StartSAP,报错信息找不到指定的模块:"Theprogramcan'tstartbecausemsvcr100.dllismissingfromyourcomputer.""无法启动此程序,因为计算机中丢失了msvcr100.dll。尝试重新安装该程序以解决此问题。" OtherTermsC,C++,runtime,VCred......
  • MBR2GPT.exe 是一个用于将磁盘从MBR分区转换为GPT分区的工具,而不会修改或删除磁盘上的
    MBR2GPT.exe是一个用于将磁盘从MBR分区转换为GPT分区的工具,而不会修改或删除磁盘上的数据。这个工具允许在Windows环境中执行转换操作,而不仅限于Windows预安装环境。它提供了一些选项来验证磁盘是否可以安全地转换,并执行实际的转换操作。在使用这个工具之前,用户可以选择进行......
  • 计算机Windows系统优化小知识
    目录目录什么是注册表优化优化工具什么是注册表注册表是保存所有系统设置数据的存储器。注册表保存了Windows运行所需的各种参数和设置,以及应用程序相关的所有信息。从Windows启动开始,到用户登录、应用程序运行等所有操作都需要以注册表中记录的信息为基础。注册表在Windows操......
  • FFmpeg开发笔记(十七)Windows环境给FFmpeg集成字幕库libass
    ​libass是一个适用于ASS和SSA格式(AdvancedSubstationAlpha/SubstationAlpha)的字幕渲染器,支持的字幕类型包括srt、ass等,凡是涉及到给视频画面添加字幕,均需事先集成libass。《FFmpeg开发实战:从零基础到短视频上线》一书的“7.3.1 Linux环境安装libass”介绍了如何在Linux环境......
  • 记录一下docker desktop windows安装,容器安装等
    安装包下载https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe    docker应用管理工具,选择性安装https://www.rainbond.com/docs/quick-start/quick-installhttps://www.bilibili.com/video/BV1MZ4y1b7wW/?p=2&spm_id_from=pageDriver&......
  • windows bilibili客户端缓存视频导出
    视频缓存地址:C:\Users\Administrator\Videos\bilibili\一串数字使用winhex把视频和音频前面的八个0删除使用ffmpeg合并视频和音频ffmpeg-i视频文件-i音频文件-codeccopy输出地址......