【PM复习】进入保护模式改进

本文介绍了一种使用宏定义简化GDT(全局描述符表)配置的方法,通过宏定义段基址、段界限和段属性,使代码更易于理解和维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     在前面的建立GDT的代码中,只是用db,dw直接来写二进制的数据,当我们要在GDT中添加很多描述符的时候,这样做就显得很晦涩难懂。在这里我们就建立1个宏,此宏以比较方便的方法来建立1个描述符,有3个入口参数,分别是段基址,段界限和段属性,代码如下:

Code:
  1. ;%1 Base   
  2. ;%2 Limit   
  3. ;%3 Attr   
  4. %macro  Descriptor 3   
  5.     dw %2 & 0ffffh   
  6.     dw %1 & 0ffffh   
  7.     db (%1 >> 16) & 0ffh   
  8.     db %3 & 0ffh   
  9.     db ((%3 >> 8) & 0ffh) | ((%2 >> 16) & 0fh)   
  10.     db (%1 >> 24) & 0ffh   
  11. %endmacro  

     我们看到,就是把入口参数通过移位和逻辑操作符来分隔到合适的地方,对照着描述符的结构就可以很轻松地完成此工作。

     还有1个地方可以抽象,就是填充描述符的段基址的代码,如果要填充很多个描述符的段基址,那么重复的代码就会很多,可以选择用函数或者宏来实现,我们这里用宏来实现吧。入口地址有2个,一个是段描述符在实模式下的偏移,另一个是目标代码段的偏移,代码如下:

Code:
  1. ;%1 Descriptor's Offset   
  2. ;%2 Segment's Offset   
  3. %macro  Fill_Descriptor 2   
  4.     xor eax,eax   
  5.     mov ax,cs   
  6.     shl eax,4   
  7.     add eax,%2   
  8.     mov word [%1 + 2],ax   
  9.     shr eax,16   
  10.     mov byte [%1 + 4],al   
  11.     mov byte [%1 + 7],ah   
  12. %endmacro  

     这样我们的代码就可以简洁很多了,下面在上一节的基础上修改的代码:

Code:
  1. ;%1 Base      
  2. ;%2 Limit      
  3. ;%3 Attr      
  4. %macro  Descriptor 3      
  5.     dw %2 & 0ffffh      
  6.     dw %1 & 0ffffh      
  7.     db (%1 >> 16) & 0ffh      
  8.     db %3 & 0ffh      
  9.     db ((%3 >> 8) & 0ffh) | ((%2 >> 16) & 0fh)      
  10.     db (%1 >> 24) & 0ffh      
  11. %endmacro     
  12.   
  13. ;%1 Descriptor's Offset      
  14. ;%2 Segment's Offset      
  15. %macro  Fill_Descriptor 2      
  16.     xor eax,eax      
  17.     mov ax,cs      
  18.     shl eax,4      
  19.     add eax,%2      
  20.     mov word [%1 + 2],ax      
  21.     shr eax,16      
  22.     mov byte [%1 + 4],al      
  23.     mov byte [%1 + 7],ah      
  24. %endmacro     
  25.   
  26. org 0100h       
  27. jmp LABEL_BEGIN       
  28.       
  29. [section .gdt]       
  30. LABEL_DESC_DUMMY:       
  31.     Descriptor  0,0,0     
  32. LABEL_DESC_CODE32:    
  33.     Descriptor  0,0ffffh,409ch      
  34. LABEL_DESC_VIDEO:       
  35.     Descriptor  0b8000h,0ffffh,4092h   
  36.            
  37. GDT_Len equ $ - LABEL_DESC_DUMMY       
  38. GDT_Ptr:       
  39.     dw  GDT_Len - 1       
  40.     dd  0       
  41.       
  42. Selector_Code32 equ LABEL_DESC_CODE32 - LABEL_DESC_DUMMY       
  43. Selector_Video  equ LABEL_DESC_VIDEO - LABEL_DESC_DUMMY       
  44.       
  45. [section .s16]       
  46. [bits 16]       
  47. LABEL_BEGIN:       
  48.     mov ax,cs       
  49.     mov ds,ax       
  50.     mov es,ax       
  51.            
  52.     Fill_Descriptor LABEL_DESC_CODE32,LABEL_CODE32   
  53.            
  54.     xor eax,eax       
  55.     mov ax,ds       
  56.     shl eax,4       
  57.     add eax,LABEL_DESC_DUMMY       
  58.     mov dword [GDT_Ptr + 2],eax       
  59.            
  60.     lgdt    [GDT_Ptr]       
  61.            
  62.     cli       
  63.            
  64.     in  al,92h       
  65.     or  al,00000010b       
  66.     out 92h,al       
  67.            
  68.     mov eax,cr0       
  69.     or  al,1       
  70.     mov cr0,eax       
  71.            
  72.     jmp Selector_Code32:0       
  73.       
  74. [section .s32]       
  75. [bits 32]       
  76. LABEL_CODE32:       
  77.     mov ax,Selector_Video       
  78.     mov gs,ax       
  79.     mov ah,0ch       
  80.     mov al,'x'      
  81.     mov [gs:80 * 10],ax       
  82.     jmp $       

     运行结果与上一节相同。

CH341A编程器是一款广泛应用的通用编程设备,尤其在电子工程和嵌入式系统开发领域中,它被用来烧录各种类型的微控制器、存储器和其他IC芯片。这款编程器的最新版本为1.3,它的一个显著特点是增加了对25Q256等32M芯片的支持。 25Q256是一种串行EEPROM(电可擦可编程只读存储器)芯片,通常用于存储程序代码、配置数据或其他非易失性信息。32M在这里指的是存储容量,即该芯片可以存储32兆位(Mbit)的数据,换算成字节数就是4MB。这种大容量的存储器在许多嵌入式系统中都有应用,例如汽车电子、工业控制、消费电子设备等。 CH341A编程器的1.3版更新,意味着它可以与更多的芯片型号兼容,特别是针对32M容量的芯片进行了优化,提高了编程效率和稳定性。26系列芯片通常指的是Microchip公司的25系列SPI(串行外围接口)EEPROM产品线,这些芯片广泛应用于各种需要小体积、低功耗和非易失性存储的应用场景。 全功能版的CH341A编程器不仅支持25Q256,还支持其他大容量芯片,这意味着它具有广泛的兼容性,能够满足不同项目的需求。这包括但不限于微控制器、EPROM、EEPROM、闪存、逻辑门电路等多种类型芯片的编程。 使用CH341A编程器进行编程操作时,首先需要将设备通过USB连接到计算机,然后安装相应的驱动程序和编程软件。在本例中,压缩包中的"CH341A_1.30"很可能是编程软件的安装程序。安装后,用户可以通过软件界面选择需要编程的芯片类型,加载待烧录的固件或数据,然后执行编程操作。编程过程中需要注意的是,确保正确设置芯片的电压、时钟频率等参数,以防止损坏芯片。 CH341A编程器1.3版是面向电子爱好者和专业工程师的一款实用工具,其强大的兼容性和易用性使其在众多编程器中脱颖而出。对于需要处理25Q256等32M芯片的项目,或者26系列芯片的编程工作,CH341A编程器是理想的选择。通过持续的软件更新和升级,它保持了与现代电子技术同步,确保用户能方便地对各种芯片进行编程和调试。
内存分区情况的分析是嵌入式系统开发中的一个重要环节,特别是在资源有限的MCU(微控制器)环境中。标题提到的工具是一款专为分析Linux环境下的`gcc-map`文件设计的工具,这类文件在编译过程结束后生成,包含了程序在目标设备内存中的布局信息。这个工具可以帮助开发者理解程序在RAM、ROM以及FLASH等存储区域的占用情况,从而进行优化。 `gcc-map`文件通常包含以下关键信息: 1. **符号表**:列出所有定义的全局和静态变量、函数以及其他符号,包括它们的地址和大小。 2. **节区分配**:显示每个代码和数据节区在内存中的位置,比如.text(代码)、.data(已初始化数据)、.bss(未初始化数据)等。 3. **内存汇总**:总览所有节区的大小,有助于评估程序的整体内存需求。 4. **重定位信息**:显示了代码和数据如何在目标地址空间中定位。 该分析工具可能提供以下功能: 1. **可视化展示**:将内存分配以图形化方式呈现,便于直观理解。 2. **详细报告**:生成详细的分析报告,列出每个符号的大小和位置。 3. **比较功能**:对比不同编译版本或配置的`map`文件,查看内存使用的变化。 4. **统计分析**:计算各种内存区域的使用率,帮助识别潜在的优化点。 5. **自定义过滤**:允许用户根据需要筛选和关注特定的符号或节区。 虽然在MCU环境中,Keil IDE自带的工具可能更方便,因为它们通常针对特定的MCU型号进行了优化,提供更加细致的硬件相关分析。然而,对于通用的Linux系统或跨平台项目,这款基于`gcc-map`的分析工具提供了更广泛的适用性。 在实际使用过程中,开发者可以利用这款工具来: - **优化内存使用**:通过分析哪些函数或数据占用过多的内存,进行代码重构或调整链接器脚本以减小体积。 - **排查内存泄漏**:结合其他工具,比如动态内存检测工具,查找可能导致内存泄漏的部分。 - **性能调优**:了解代码执行时的内存分布,有助于提高运行效率。 - **满足资源限制**:在嵌入式系统中,确保程序能在有限的内存空间内运行。 总结来说,`gcc-amap`这样的工具对于深入理解程序的内存布局和资源消耗至关重要,它能帮助开发者做出更明智的决策,优化代码以适应不同的硬件环境。在处理`map`文件时,开发者不仅能获取到程序的内存占用情况,还能进一步挖掘出可能的优化空间,从而提升系统的整体性能和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值