精华内容
下载资源
问答
  • C语言汇编语言相互调用原理以及实例 1.原理 其实不管是C语言还是汇编语言想要执行都是最终编译链接成为二进制文件。 这里一定要明确编译和链接是两个步骤,生成的文件格式也是不一样的。 编译生成的文件是一定格式...

    C语言与汇编语言相互调用原理以及实例

    1.原理

    其实不管是C语言还是汇编语言想要执行都是最终编译链接成为二进制文件。
    这里一定要明确编译和链接是两个步骤,生成的文件格式也是不一样的。
    编译生成的文件是一定格式的,里面包括函数符号表、参数表...等信息,这些信息主要是提供给链接阶段使用,函数调用是怎么调用的?是不是指定利用的函数的符号?所以链接阶段就是将函数调用的符号变成相对地址(要特别注意这个阶段,因为这个过程使得C语言和汇编语言相互调用成为可能)

    2.下面两个分别是一个hello.asm(汇编语言文件),main.c(c语言文件)

    ;hello.asm
    extern print_helloworld  
    [section .text]  
    global print_two_hello_world  
    print_two_hello_world:    
    call print_helloworld  
    call print_helloworld  
    
    /* main.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_helloworld(),此函数是C语言定义的一个函数。接下来是定义了一个函数print_two_hello_world,用global关键字导出使其可以在C中调用,函数的内容是调用了两次print_helloword()。
    在来看C代码,代码很简单就具体讲了,这里主要数一下我们将主函数放在了C代码中写,这时因为我们要使用C代码的函数库中的printf()函数,如果C代码中没有什么库的依赖可以将主函数放在汇编代码中

    3.NASM和C互相调用对方的变量

    Nasm代码

     global string  
    extern strhello  
    [section .data]  
    string:  
        db 'I am Chinese.',0x0A,0x0  
    [section .text]  
        global print_hello  
        global cpy_mem  
    print_hello:      
        mov edx, 13  
        mov ecx,[strhello]  
        mov ebx,1  
        mov eax,4  
        int 0x80  

    C代码

    #include "stdio.h"  
    #include "string.h"  
    extern char *string;  
    extern void print_hello();  
    extern cpy_mem (void *dest, int len);  
    char *strhello = "Hello,world!\n";  
    char *str = NULL;  
    int  
    main ()  
    {  
            printf ("%x\n",&string);  
            str = &string;  
            printf ("%s", str);  
             
            print_hello ();  
            return 0;  
    }  

    Make后的执行结果如下:
    I am Chinese.
    Hello,world!
    具体的代码内容就部分析了,这里主要将两个关键的地方。

    1.在C语言中定义了一个strhello的字符串变量,在C语言中strhello表示的是字符串的首地址,比如字符串的地址是0xa00001,而strhello是个指针即4字节其地址为0xb00001, 在C语言中strhello表示的值是 0xa00001 字符串的首地址,但到了NASM中则表示的 strhello变量的首地址了 0xb00001,所以

    Nasm代码

    mov ecx,[strhello]  

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

    2.第二点要注意的是,在NASM中定义了一个字符串string , 在C语言中导入的话,就是表示字符串的首地址,因此要引用该字符串一定要取其地址,不要直接转为(char*)类型直接用,否则出错,这是因为直接转的话,就将字符串的前4个字节转成了字符串指针,但该指针是不确定会出现段错误!

    转载于:https://www.cnblogs.com/liubiyonge/p/9415137.html

    展开全文
  •  本文旨在描述怎么将C语言汇编语言中的宏展开,为什么要展开?不知大伙有没有调试过宏定义的代码,是不是不能调试,需要手工去掉宏之后才能调试。当然本文不是教你怎么用手工的方法展开宏,而是预编译的方式。 ...

     本文旨在描述怎么将C语言或汇编语言中的宏展开,为什么要展开?不知大伙有没有调试过宏定义的代码,是不是不能调试,需要手工去掉宏之后才能调试。当然本文不是教你怎么用手工的方法展开宏,而是预编译的方式。

    C语言中的宏

    工具Visual Studio 2013, 注意,一定要Visual Studio 2013及以上版本,使用其自带的cl.exe编译器,关于cl.exe打开方法:开始-》所有程序-》Visual Studio 2013-》Visual Studio Tools 用VS2013 x86本机工具命令提示。

    cl.exe -I../../  input.c  -P -Fioutput.list
    注意
    1、-Fi后面跟的是预处理后的文件名
    2、input.c是输入的c文件,里面有各种宏
    
    展开全文
  • C语言汇编语言相互调用原理以及实例##1.原理 其实不管是C语言还是汇编语言想要执行都是最终编译链接成为二进制文件。 这里一定要明确编译和链接是两个步骤,生成的文件格式也是不一样的。 编译生成的文件是一定...

    C语言与汇编语言相互调用原理以及实例

    ##1.原理 其实不管是C语言还是汇编语言想要执行都是最终编译链接成为二进制文件。 这里一定要明确编译和链接是两个步骤,生成的文件格式也是不一样的。 编译生成的文件是一定格式的,里面包括函数符号表、参数表...等信息,这些信息主要是提供给链接阶段使用,函数调用是怎么调用的?是不是指定利用的函数的符号?所以链接阶段就是将函数调用的符号变成相对地址(要特别注意这个阶段,因为这个过程使得C语言和汇编语言相互调用成为可能)

    ##2.下面两个分别是一个hello.asm(汇编语言文件),main.c(c语言文件) ;hello.asm extern print_helloworld

    [section .text]

    global print_two_hello_world

    print_two_hello_world:

    call print_helloworld

    call print_helloworld

    /* main.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_helloworld(),此函数是C语言定义的一个函数。接下来是定义了一个函数print_two_hello_world,用global关键字导出使其可以在C中调用,函数的内容是调用了两次print_helloword()。 在来看C代码,代码很简单就具体讲了,这里主要数一下我们将主函数放在了C代码中写,这时因为我们要使用C代码的函数库中的printf()函数,如果C代码中没有什么库的依赖可以将主函数放在汇编代码中

    ##3.NASM和C互相调用对方的变量 Nasm代码

    global string

    extern strhello

    [section .data]

    string:

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

    [section .text]

    global print_hello

    global cpy_mem

    print_hello:

    mov edx, 13

    mov ecx,[strhello]

    mov ebx,1

    mov eax,4

    int 0x80

    C代码

    #include "stdio.h"

    #include "string.h"

    extern char *string;

    extern void print_hello();

    extern cpy_mem (void *dest, int len);

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

    char *str = NULL;

    int

    main ()

    {

    printf ("%x\n",&string);

    str = &string;

    printf ("%s", str);

    print_hello ();

    return 0;

    }

    Make后的执行结果如下: I am Chinese. Hello,world! 具体的代码内容就部分析了,这里主要将两个关键的地方。

    1.在C语言中定义了一个strhello的字符串变量,在C语言中strhello表示的是字符串的首地址,比如字符串的地址是0xa00001,而strhello是个指针即4字节其地址为0xb00001, 在C语言中strhello表示的值是 0xa00001 字符串的首地址,但到了NASM中则表示的 strhello变量的首地址了 0xb00001,所以

    Nasm代码

    mov ecx,[strhello]

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

    2.第二点要注意的是,在NASM中定义了一个字符串string , 在C语言中导入的话,就是表示字符串的首地址,因此要引用该字符串一定要取其地址,不要直接转为(char*)类型直接用,否则出错,这是因为直接转的话,就将字符串的前4个字节转成了字符串指针,但该指针是不确定会出现段错误!

    展开全文
  • 同时呢,汇编语言也是其他很多高级语言通向机器的一个桥梁,比如c语言需要编写好后再编译成汇编语言,再转换为机器语言。 这样的话就可以自然想到,是不是我可以通过一些反编译的手段去破解一些软件或者其他的呢...

    引言

    汇编语言是除了机器语言外,最为底层的编程语言。由于机器只能读懂0和1,所以需要转换成人类更易操作的语言(其实设计c等高级语言的原因也包括这点)。

    同时呢,汇编语言也是其他很多高级语言通向机器的一个桥梁,比如c语言需要编写好后再编译成汇编语言,再转换为机器语言。

    这样的话就可以自然想到,是不是我可以通过一些反编译的手段去破解一些软件或者其他的呢(逆向工程)?

    其实也不然,只有机器语言和汇编语言是一一对应的,而高级语言很可能一句话就代表了很多汇编语言的操作,所以正向容易而逆向容易出错。例如一个用c语言编写的程序,不可能被人直接把源代码给破解出来的。这时候就需要用到汇编语言了(黑客最爱)

    总之,由于汇编和机器是关联非常密切的,所以学习汇编语言可以让我们更加了解硬件的运作,如何让硬件更有效率的工作。

    本博客主要是根据汇编语言与接口技术第四版,以及小甲鱼网课(地址:fishc.com)来写。本人大三计算机专业,第一次学习汇编语言,笔记仅适用于初学者借鉴,如有疏漏望大佬指出。

    1.1 汇编语言的产生

    机器语言是机器指令的集合;
    而汇编语言的主体也是汇编指令。

    两种指令区别在于表示方式上,通俗来讲,汇编指令是在机器指令的基础上写成了一种便于我们记忆的格式。定义上来讲,汇编指令叫做机器指令的助记符。

    这里举个例子:
    比如一个操作的内容是:将寄存器AX的内容移动到寄存器BX中。

    用机器语言来写是这样的:1000100111011000

    是不是根本看不懂?那么汇编指令呢,就对其进行格式变换,写成了汇编的语言:
    MOV BX,AX

    mov的意思就是move移动,一般都取三个字母,这样看就很好理解了。值得注意的是,是将后面的移动到前面的,具体操作后面再讲。

    寄存器

    我们刚才提到了AX BX这些寄存器,这些是什么东西呢?

    简单来讲,可以理解为cpu中的内存(注意跟一级二级缓存区分)。一个cpu里面有各种各样的寄存器,比如标志寄存器啊数据寄存器啊等等,每个都有自己的任务。目前只需要知道它们是存储数据啊指令什么的。
    而AX和BX这种,暂时理解为寄存器的代号吧(小甲鱼是这么说的)

    1.2 汇编语言的组成

    汇编语言主要由以下三个部分组成:

    1. 汇编指令(即机器语言的助记符),也是汇编语言的核心。比如MOV add之类的,后续跟随的操作数也放在一起。
      先放一张8086的指令格式图,慢慢理解是可以看懂的。
      在这里插入图片描述

    2. 伪指令。
      伪指令要区别于汇编指令,汇编指令是可以产生供机器执行的对应机器代码的,而伪指令不会,它主要用于辅助源程序的汇编。比如指定数据存放地址等。这些指令机器无法识别,是通过编译器来识别并执行的。
      具体例子可以参考这个https://blog.csdn.net/houyichaochao/article/details/80686076

    3. 其他符号。
      比如加减乘除什么的,也是跟伪指令一样,需要编译器去识别和执行。

    1.3 存储器

    计算机中的大部分部件都有自己的存储器,我们这里主要学习的是内存

    CPU是负责控制整个计算机的运行和运算,但是我们不能把数据什么的直接放到CPU中(因为实在太多了,cpu又那么贵),所以我们一般会选择硬盘存放。但是CPU又不能直接从硬盘中读取数据,这时候就需要内存这个东西。

    内存里面需要存放CPU需要处理的指令和数据。指令的意思是告诉CPU要做什么操作,数据则是告诉CPU要对什么东西操作。

    在内存或者硬盘上,数据和指令没有什么区别,都是一些二进制的代码。
    比如:
    1000100111011000 —> 89D8H (数据)
    1000100111011000 —> MOV AX,BX (指令)
    具体代表哪一种,是人为说了算的。

    1.4 存储单元

    存储器会被划分为若干个存储单元,每个存储单元从0开始编号。比如假如一个存储器有128个存储单元,他们的编号就是0~127.

    一个存储单元可存放1Byte。1KB的存储器有0~1023共1024个存储单元。

    1.5 CPU对内存的读写——总线

    前面我们说了,CPU自己不存那么多的数据,而是从内存中获取,主要获取的东西有三类:

    • 存储单元的地址(地址信息)
    • 器件选择以及读写命令(控制信息)
    • 读写的数据(数据信息)

    那么究竟这些信息是如何传输的呢?

    我们应该都听说过电信号这个东西,如下:

    电平脉冲

    电子计算机能够处理和传输的信号都是电信号,所以要用导线传输。

    如果你有过自己装电脑的经历,印象最深刻的一定是插线过程(实在是太麻烦了……)。你所插的那些线,就是总线(Bus)的一部分。

    总线在逻辑上分为:

    • 地址总线
    • 数据总线
    • 控制总线

    也是分别对应了上面所说的三种信息。

    图源自小甲鱼网课

    读

    仔细看,地址线中,CPU将自己需要操作的对象的地址发送给内存,告诉内存我现在需要这个地址里的东西。

    读
    接着控制线中,CPU发给内存读的信息,告诉它我现在需要进行的操作是读取。

    读

    然后内存便知道自己需要做什么了,就将地址号为3的数据交给了CPU。

    至于写的指令,和读是一样的,只不过数据是从CPU到内存的。
    写

    还记不记得上面提到过,说在内存中指令和数据时无法区分的,两个一样的机器代码既可以代表一种操作,又可以代表一串数据。当时我们只是说可以人为认定它代表什么,而现在我们知道了,从哪条线走的,就是代表哪一类。

    如果你见过CPU芯片,肯定就见过黄色的那些针脚(也交管脚),它们是和总线相连的。也可以说这些针脚引出了总线。

    一个CPU可以引出的三种总线的宽度分别代表了它在三个方面的性能:

    • 地址总线宽度决定了CPU的寻址能力
    • 数据总线宽度决定了数据传输一次的数据量
    • 控制总线宽度决定了其对其他部件的控制能力

    1.5.1 地址总线

    通过上面的图我们能知道地址总线是用来传输地址的线,这里我们稍微多讲一点。

    你们肯定都知道现在的电脑一般都是64或者32位的,但这个可以理解为双重的概念,即操作系统的位数和CPU的位数。两者是有关联的,简单来说,如果CPU是64位的,操作系统如果低于,就不能完全发挥CPU的性能。

    对于CPU的这个参数,它代表的意思是寻址的能力。比如64位的处理器可以寻址2的64次方个地址。理论上来讲每条地址线就有一条导线,所以看起来64位处理器有64条,但实际上不一定是。

    更准确一点的说法是,一个CPU有N条地址线,就可以说这个CPU的地址总线宽度为N,可以寻找2的N次方个内存单元。地址总线上能传送多少个不同的信息,CPU就可以对多少个存储单元进行寻址。

    1.5.2 数据总线

    数据总线同样也有宽度,它决定了数据传输的速度。

    就像是公路一样,公路越宽,单位时间走的车就越多(因为速度都差不多一样,好像叫什么震荡频率啊什么的)。

    同样也可以用位数来理解。

    比如8086处理器,它是16位的数据总线。
    如果我们要传输某个数据,它的二进制代码是1101100010001001正好16位,我们就可以一次传输完毕:

    8086

    如果是8088处理器的话,因为这是一个8位的CPU,所以需要传递两次。注意是从低到高。

    这也是位数增加运算速度更快的原因,想想现在的64位CPU

    1.5.3 控制总线

    控制总线是控制线的总称,控制线主要是CPU对其他器件的控制。

    所以有多少跟控制线,就意味着CPU可以对其他器件有多少种控制。

    需要知道的是,之前讲的读写命令是由好几根控制线综合发出的,具体的教材上好像不要求掌握,就不多赘述了。


    本章结束,注意以上内容均为理论,对实际情况不做讨论。

    展开全文
  • 可移植性就是指编译后的文件在不同的操作系统中都可以直接运行,所以汇编语言C语言可移植性都很差,如果更换平台需要重新编译一遍才可以运行(这里我产生了第一个疑问,就是汇编语言的等级和汇编语言是否可以讨论...
  • 汇编语言入门到精通 什么是汇编语言 首先我们先来 理解一下什么是语言 他是人与人沟通的方式,比如两个人之间使用不同话交流,那么普通话就是他们之间的语言 那么 这时, 突然来了个老外,他讲的是英语,那是不是就...
  • 前几篇文章我也发了很多有关C语言的学习资源,如果大家想要学习黑客或者是渗透相关的技术,那么学习C语言是不是必要的呢?今天小编说说黑客为什么要学习C语言。 精通C语言的黑客才是真正的黑客 黑客界,有两样重要...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    1. C语言汇编语言在开发单片机时各有哪些优缺点? 答:汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言...
  • 随着单片机开发技术的不断发展,目前已有越来越多的人从普遍使用汇编语言到逐渐使 用高级语言开发,其中主要是以C 语言为主,市场上几种常见的单片机均有其C 语言开发 环境。这里以最为流行的80C51 单片机为例来学习...
  • c语言实现字符串左旋

    2021-05-22 22:28:14
    汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出...
  • 单片机的c语言具有可移植性好,易懂易用的特点,在我国有大量的c程序员,重新学习单片机将非常容易,因此,虽然汇编语言更精炼,但是使用c也是大势所趋! 单片机的c语言教程...由磁动力工作室明浩编写.51测试网友...
  • 你必须知道的495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都解决了,是吗? 1.4 新的64位机上的64位类型...
  • 难道在C语言中一个结构不能包含指向自己的指针吗? o 2.7 怎样建立和理解非常复杂的声明?例如定义一个包含 N 个指向返回指向字符的指针的函数的指针的数组? o 2.8 函数只定义了一次, 调用了一次, 但编译器提示...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    C是一门简洁精妙的语言,掌握基本语法容易,真正能够自如运用,就不那么简单了。你难免会遇到各种各样的问题,有些可能让你百思不得其解,甚至翻遍图书馆,也找不到问题的答案。 《你必须知道的495个C语言问题》的...
  • 1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都解决了,是吗? 2  1.4 新的64位机上的64位...
  • 你必须知道的495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    2.11 为什么sizeof 返回的值大于结构的期望值, 是不是尾部有填充? . . 9 2.12 如何确定域在结构中的字节偏移? . . . . . . . . . . . . . . . . . 9 2.13 怎样在运行时用名字访问结构中的域? . . . . . . . . . . ...
  • 最近看完了“《汇编语言(第3版)》王爽著”,该书是基于DOS环境和TC2编译器讲的,老掉牙了是不是,不过看完了还是很有收获的.下面分析两段C语言程序生成的汇编指令,作为看完这本书后的总结.通过分析这两个程序可以明白...
  •  我们如何理解这句话呢,c语言是用高级语言编写的机器不能直接执行(机器语言才能直接执行,例如汇编语言),需要先编译、链接,最终生成可执行的二进制文件,机器才能执行。  但是我们学习python的时候,说它是...
  • 不知大家注意过没有,不仅人类有语言:汉语,英语,法语,拉丁语,日语等等,和计算机打交道也要通过语言,C语言,C++,JAVA,BASIC,PASCAL,各种汇编语言,……。既然都叫语言,是不是有什么共性的东东,好让大家...
  • 不知大家注意过没有,不仅人类有语言:汉语,英语,法语,拉丁语,日语等等,和计算机打交道也要通过语言,C语言,C++,JAVA,BASIC,PASCAL,各种汇编语言,……。既然都叫语言,是不是有什么共性的东东,好让大家...
  • 关于初学51单片机

    2014-04-26 23:34:23
    说到这个核心编程,从硬件的角度来说,最好选择使用汇编语言进行编程,因为汇编语言是最底层的硬件语言,可以实现高效的控制,执行效率很高。但是从实用性,以及开发者来说C语言编程比较合适,C语言与有很好的兼容性...
  • [quote] yinyousong: 很多程序员多在抱怨java的new浪费了太多的内存,应该大量的使用static。但依据我观察banq老师的文章来看,banq老师似乎对...书中提到:汇编语言是对底层机器的轻微抽象,C语言是在汇编语言的基...
  • 不过,在所有这一切开始以前,先打好C语言汇编基础。 能不能得道,就看你在见到别人做出一些花里胡哨的东西时,是不是能坚定信心、耐住寂寞、抵御诱惑了。 一个和我一起学习C语言的人,学完就直接开始玩VC,而...
  • 微信公众号:javafirst你是不是还在怀念曾经逝去的...比如,你选择了计算机专业,那么你将面临高等数学、线性代数、C语言、计算机引论、离散数学、电子技术、C++程序设计、汇编语言程序设计、计算机组成原理、...
  • 高考---程序员版

    2018-06-15 17:08:14
    微信公众号:javafirst你是不是还在怀念曾经逝去的...比如,你选择了计算机专业,那么你将面临高等数学、线性代数、C语言、计算机引论、离散数学、电子技术、C++程序设计、汇编语言程序设计、计算机组成原理、...
  • C# 2.0 Essential Examples

    2010-09-15 19:54:43
    适合Junior到Senior的C#2.0 快速参考 或者是那种经常用不同语言开发的人员复习 ...C#支持的汇编,这里没有说明,事实上,我不确定C#2.0的时候是不是已经支持汇编了 其他几乎类C语言里的各种功能C#里都包括了

空空如也

空空如也

1 2 3
收藏数 41
精华内容 16
关键字:

c语言是不是汇编语言

c语言 订阅