汇编中有几种寻址方式,分别是直接寻址:(ds:[idata])、寄存器间接寻址(ds:[bx])、寄存器相对寻址(ds:[bx + idata]、ds:[bx + si])基址变址寻址(ds:[bx + si])、相对基址变址寻址([bx + si + idata])。

结构体的存储逻辑图如下:(以下数据表示某公司的名称、CEO、CEO的福布斯排行、收入、代表产品)



现在假设公司的CEO在富豪榜上的排名为38,收入增加了70,代表产品变为VAX,通过汇编编程修改上述信息,以下是相应的汇编代码:(假设数据段为seg)

mov ax,seg
mov ds,ax
mov bx,0
mov word ptr ds:[bx + 12],38
add [bx + 14],70
mov si,0
mov byte ptr [bx + 10 + si],'V'
inc si
mov byte ptr [bx + 10 + si],'A'
inc si
mov byte ptr [bx + 10 + si],'X'

对应的C语言代码可以写成:

struct company 

{
char cn[3];
char name[9];
int pm;
int salary;
char product[3]; };
company dec = {"DEC","Ken Olsen",137,40,"PDP"};
int main()
{
int i;
dec.pm = 38;
dec.salary += 70;
dec.product[i] = 'V';
++i;
dec.product[i] = 'A';
++i;
dec.product[i] = 'X';
return 0; }

对比C语言代码和汇编代码,可以看出,对于结构体变量,系统会先根据定义分配相应大小的空间,并将各个变量名与内存关联起来,结构体对象名与系统分配的空间的首地址相对应(定义的结构体对象的首地址在段中的相对地址存储在bx中),即在使用dec名时实际与汇编代码“mov ax,seg” “mov ds,ax”

对应,将数据段段首地址存入ds寄存器中,系统根据对象中的变量名找到对应的偏移地址,偏移地址的大小由对应的数据类型决定,如cn数组前没有变量,cn的偏移地址为0,cn所在的地址为 ds:[bx],cn为长度为3的字符型数组,在上一个偏移地址的基础上加上上一个变量所占空间的大小即为下一个变量的偏移地址,所以name数组的首地址为ds:[bx + 3],这样给出了对象名就相当于给定了该对象在段中的相对地址(上述代码中的bx),给定了对象中的成员变量名就相当于给定了某一内存在对象中的偏移地址(ds:[bx + idata])。根据数组名可以找到数组的首地址,但数组中具体元素的访问则需要给定元素个数,即si的值来定位数组中的具体内存,C语言中的 ++i 相当于汇编中的 (add si ,数组中元素的长度)。

根据以上的分析可以看出,构建一个结构体对象时,系统会在代码段中根据结构体的定义开辟相应大小的内存空间,并将该空间在段中的偏移地址与对象名绑定。对象中的变量名与该变量在对象所在内存中的偏移地址相关联,数组中的标号用于定位数组中的元素在数组中的相对位置。(对象名决定bx,变量名决定bx + idata,数组中的元素标号决定bx + idata + si)。

C语言中处理结构体的原理的更多相关文章

  1. C语言中的结构体,结构体数组

    C语言中的结构体是一个小难点,下面我们详细来讲一下:至于什么是结构体,结构体为什么会产生,我就不说了,原因很简单,但是要注意到是结构体也是连续存储的,但要注意的是结构体里面类型各异,所以必然会产生内存 ...

  2. Verilog缺少一个复合数据类型,如C语言中的结构体

    https://mp.weixin.qq.com/s/_9UsgUQv-MfLe8nS938cfQ Verilog中的数据类型(Data Type)是分散的,缺少一个复合数据类型:把多个wire, r ...

  3. C语言中的结构体和C++中的结构体以及C++中类的区别

    c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一. ...

  4. C语言中的结构体

    用户自己建立自己的结构体类型 1.  定义和使用结构体变量 (1).结构体的定义 C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体. (2).声明一个结构体类型的一般形式为: ...

  5. c语言中的结构体指针类型的cast

    1.我们在c语言中会经常碰到强制类型转换. 在这,我介绍一种结构pointer类型转换,但是有前提(有点类似于c++中的继承中的子父对象的cast). 简单的介绍一下: 首先我们要知道一个结构的指针, ...

  6. 018_go语言中的结构体

    代码演示 package main import "fmt" type person struct { name string age int } func main() { fm ...

  7. Go语言中的结构体 (struct)

    Golang官方称Go语言的语法相对Java语言而言要简洁很多,但是简洁背后也灵活了很多,所以很多看似很简单的代码上的细节稍不注意就会产生坑.本文主要对struct结构体的相关的语法进行总结和说明. ...

  8. C语言中全局结构体指针隐含的错误

    前天在嵌入式系统上,调试一个数组的全局变量时,发现该变量一直会动态变化.深入分析, 才发现该全局结构体没有申请内存,而是用了一个指针.这种情况编译器是检查不出来的,在linux 上运行会挂掉,但是在裸 ...

  9. C语言中的结构体是怎么定义的_怎么使用?

    结构体的定义 // 定义结构体st struct st{ int a; // 成员a int b; // 成员b }; #include <stdio.h> struct st{ int ...

随机推荐

  1. Deming管理系列(2)——怎样开发度量能力

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTI1MDQ1NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  2. .NET Core 已经实现了PHP JIT,现在PHP是.NET上的一门开发语言

    12月23日,由开源中国联合中国电子技术标准化研究院主办的2017源创会年终盛典在北京万豪酒店顺利举行.在本次大会上,链家集团技术副总裁.PHP 开发组核心成员鸟哥发表了以 " PHP Ne ...

  3. Swiper单页网站简单案例(全屏网页)

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  4. 第五章——定时器Timer序言

    定时器很重要. 上家公司有用的,是用来做定期数据同步的. 以前老同学有用到,曾经就定时器讨论过一次,还给过一次他我关于spring-task的总结. 但是并没有意识到定时器与多线程的关系,或者说,上一 ...

  5. springmvc返回json字符串中文乱码问题

    问题: 后台代码如下: @RequestMapping("menuTreeAjax") @ResponseBody /** * 根据parentMenuId获取菜单的树结构 * @ ...

  6. itextpdf添加非自带字体(例如微软雅黑)

    找到需要的字体,例如 在windows系统中找到需要字体,本例使用微软雅黑,使用C:\\Windows\\Fonts\\msyh.ttf. 代码如下: /** * 创建pdf,使用微软雅黑字体 * * ...

  7. Java加密与解密笔记(二) 对称加密

    前面的仅仅是做了编码或者摘要,下面看看真正的加密技术. DES public class DESUtil { static final String ALGORITHM = "DES&quo ...

  8. C#:StreamReader读取.CSV文件(转换成DataTable)

    using System.Data; using System.IO; /// <summary> /// Stream读取.csv文件 /// </summary> /// ...

  9. 关于mysql使用命令行时出现Data too long for column的解决方案:

    方法一: 1,在mysql根目录下找到my.ini文件: 2:将其中sql-mode中的STRICT_TRANS_TABLES这个属性去掉: 3:重启mysql的服务(注意注销电脑不会重启mysql服 ...

  10. 查找 GPU 计算能力

    你能在这里找到你的 GPU 的计算能力: https://en.wikipedia.org/wiki/CUDA#Supported_GPUs