当前位置: 首页 > web >正文

《汇编语言:基于X86处理器》第11章 复习题和练习

本篇记录了《汇编语言:基于X86处理器》第11章 复习题和练习的笔记。

11.7复习题和练习

11.7.1 简答题

1.写出与下面标准MS-Windows类型匹配的MASM 数据类型:

a.BOOL b.COLORREF c.HANDLE

d.LRPSTR e. WPARAM

答:a.BOOL =>DWORD b.COLORREF =>DWORD c.HANDLE =>DWORD

d.LRPSTR =>DWORD e. WPARAM =>DWORD

2.哪个 Win32 函数返回标准输入的句柄?

答:GetStdHandle函数。原型如下:

GetStdHandle PROTO,nStdHandle:HANDLE			;句柄类型

3.哪个Win32 函数从键盘读取一个字符串,并将其放入缓冲区?

答:ReadConsole函数,原型如下:

ReadConsole PROTO,hConsoleInput:HANDLE,					;输入句柄lpBuffer:PTR BYTE,						;缓冲区指针nNumberOfCharsToRead:DWROD		;读取的字符数lpNumberOfCharsRead:PTR DWORD	;指向读取字节数的指针lpReserved:DWORD							;未使用

4.请描述 COORD 结构。

答:

COORD STRUCT X WORD ?Y WROD ?
COORD ENDS

5.哪个 Win32函数能以文件开始为基址,将文件指针移动到指定偏移量的位置?

答:SetFilePointer函数。原型如下:

SetFilePointer PROTO,	hFile:HANDLE,							;文件句柄lDistanceToMove:SDWORD,				;指针移动字节数lpDistanceToMoveHigh:PTR SDWORD,	    ;指针移动字节数,高双字dwMoveMethod:DWORD					;移动方式,可取值为 FILE_BEGIN, FILE_CURRENT 或 FILE_END

6.哪个 Win32 函数能修改控制台窗口标题?

答:SetConsoleTitle函数。原型如下:

SetConsoleTitle PROTO,			; 设置控制台标题lpConsoleTitle:PTR BYTE		; 指针字符串

7.哪个Win32 函数能修改屏幕缓冲区的外形尺寸?

答:SetConsoleWindowInfo函数。原型如下:

SetConsoleWindowInfo PROTO,hConsoleOutput:HANDLE,				;屏幕缓冲区句柄bAbsolute:DWORD,						;坐标类型lpConsoleWindow:PTR SMALL_RECT		;矩形窗口指针

8.哪个Win32 函数能修改光标大小?

答:SetConsoleCursorInfo函数。原型如下:

CONSOLE_CURSOR_INFO STRUCTdwSize		DWORD ?bVisible	DWORD ?
CONSOLE_CURSOR_INFO ENDSSetConsoleCursorInfo PROTO,hConsoleOutput:HANDLE,lpConsoleCursorInfo:PTR CONSOLE_CURSOR_INFO

9.哪个Win32函数能修改后续输出文本的颜色?

答:SetConsoleTextAttribute函数。函数原型如下:

SetConsoleTextAttribute RPOTO,hConsoleOutput:HANDLE,				;控制台输出句柄wAttributes:WORD						;颜色属性

10.哪个Win32函数能将一组属性值复制到控制台屏幕缓冲区的连续单元格?

答:WriteConsoleOutputAttribute函数。函数原型如下:

WriteConsoleOutputAttribute PROTO,hConsoleOutput:DWORD,					;输出句柄lpAttribute:PTR WORD,					;写属性nLength:DWORD,						;单元格数dwWriteCoord:COORD,					;第一个单元格坐标lpNumberOfAttrsWritten:PTR DWORD		;输出计数

11.哪个 Win32 函数能按指定毫秒数暂停程序?

答:Sleep函数。函数原型如下:

Sleep PROTO, dwMilliseconds:DWORD

12.调用CreateWindowEx时,如何将窗口外观信息传递给该函数?

答:根据CreateWindowEx声明属性,传递相关字段即可。原型如下:

CreateWindowExA PROTO,	; create and register a window classexWinStyle:DWORD,className:PTR BYTE,winName:PTR BYTE,winStyle:DWORD,X:DWORD,Y:DWORD,rWidth:DWORD,rHeight:DWORD,hWndParent:DWORD,hMenu:DWORD,hInstance:DWORD,lpParam:DWORD

13.请说出两个在调用 MessageBox 函数时会用到的按钮常量。

答:MB_OK按钮, MB_OKCANCEL函数

14.请说出两个在调用MessageBox 函数时会用到的图标常量。

答:问号(?):MB_ICONQUESTION,信息符(i):MB_ICONINFORMATION.

15.请说出至少 3 个由 WinMain(启动)过程执行的任务。

答:每个Windows应用程序都需要一个启动过程,通常将其命名为WinMain,该过程负责下述任务:

得到当前程序的句柄。

加载程序的图标和光标。

注册程序的主窗口类,并标识处理该窗口事件消息的过程。

创建主窗口。

显示并更新主窗口。

开始接收和发送消息的循环,直到用户关闭应用程序窗口。

16.请说明WinProc过程在示例程序中的作用。

答:WinProc过程用来处理所有与窗口有关的事件消息,例如鼠标点击,拖动,按键等事件操作。

17.示例程序中的WinProc过程处理哪些消息?

答:WM_CREATE创建主窗口的消息,WM_LBUTTONDOWN鼠标左键按下产生的消息,WM_CLOSE关闭应用程序主窗口产生的消息。

18.请说明 ErrorHandler 过程在示例程序中的作用。

答:在示例程序中的作用是若CreateWindowEx失败,则显示消息并退出。

19.CreateWindow调用后立刻激活的消息框出现在应用程序主窗口之前还是之后?

答:CreateWindow调用后立刻激活的消息框出现在应用程序主窗口之前

20.由WM_CLOSE 激活的消息框出现在关闭主窗口之前还是之后?

答:由WM_CLOSE 激活的消息框出现在关闭主窗口之前。

21.请对线性地址进行说明。

答:线性地址由段选择符(16位的段地址)加逻辑地址(32位的偏移量)组成。线性地址是一个32位整数,其范围为0FFFFFFFFh,它表达一个内存位置。如果禁止分页功能,那么线性地址也就是目标数据的物理地址。

22.线性内存与分页之间存在怎样的关系?

答:如果禁止分页功能,那么线性内存也就是目标数据的物理地址。若请允许分页,则处理器必须将32位线性地址转换为32位物理地址。这个过程会用到3种结构:页目录:(10位),页表(10)位,页(12位)这3个字段分别表示:页目录表项指针、页表项指针和页内偏移量。

23.如果禁用分页,处理器如何将线性地址转换为物理地址?

答:如果禁用分页,处理器直接将线性地址作为物理地址。

24.分页有哪些好处?

答:分页有以下以个好处:

a. 简化内存管理

非连续分配:允许进程的物理内存分散在不相邻的区域,避免连续内存分配(如分段)导致的碎片问题。

固定大小单元:以固定大小的“页”为单位管理内存,操作系统只需维护页表,无需处理复杂的内存块匹配。

b. 提高内存利用率

减少外部碎片:通过小页划分,减少因内存分配/释放产生的碎片(外部碎片几乎被消除)。

共享内存:不同进程可以共享相同的代码页(如库文件),节省物理内存空间。

c. 支持虚拟内存

按需加载:只有当前需要的页才加载到物理内存,其余保留在磁盘(如交换空间),突破物理内存容量限制。

懒加载(Lazy Loading):程序启动时无需加载全部代码和数据,加快启动速度。

d. 提升多任务性能

快速上下文切换:进程切换时只需切换页表(如CR3寄存器),无需移动物理内存内容。

并行执行:多个进程可以高效共享物理内存,系统能同时运行更多程序。

e. 内存保护与安全

权限控制:每页可单独设置读写执行权限(如代码页只读),防止非法访问。

隔离性:进程的地址空间通过页表隔离,增强系统稳定性。

f. 优化磁盘I/O

页面置换算法:当内存不足时,通过算法(如LRU)将不活跃的页换出到磁盘,优先保留高频访问页。

预取(Prefetching):根据局部性原理预加载可能需要的页,减少缺页中断。

g. 灵活性与可扩展性

支持大地址空间:32位系统可通过分页访问超过4GB的虚拟地址空间(如PAE扩展)。

多级页表:平衡内存占用与查找效率(如x86-64的四级页表)。

25.哪个寄存器包含了局部描述符表的基地址?

答:局部描述符表寄存器(LDTR)包含了局部描述符表的在基地址。 LDTR 是一个 48 位的寄存器,其结构与 GDTR 类似,其中高 32 位用于存储 LDT 的基地址,低 16 位则表示表的大小限制(值为表长度减 1)

26.哪个寄存器包含了全局描述符表的基地址?

答:全局描述符表寄存器(GDTR)包含了全局描述符表的基地址。 GDTR 是一个 48 位的寄存器,其中低 16 位用于存储 GDT 的界限(即表的大小减一),而高 32 位则用于存储 GDT 的起始地址。

27.允许存在多少全局描述符表?

答:系统全局仅需一个GDT(但可动态替换):虽然理论上可以存在多个GDT(通过LGDT指令加载不同的基址和界限),但同一时刻只有一个GDT是活动的。操作系统通常会在任务切换或模式切换时修改GDT内容或重新加载新的GDT

28.允许存在多少局部描述符表?

答: 每个LDT本质上是一个内存段,其大小受限于内存可用空间。LDT的大小最多可包含8192个描述符条目,因此每个LDT的存储需求决定了系统中能容纳的LDT总数。

29.请说出至少 4个段描述符内的字段。

答:段描述符(segment descriptor)是一个64位的值,用于标识和描述一个内存段。它包含的信息有段基址、访问权限、段限长、类型和用法。

30.分页处理涉及哪些结构?

答:分页处理涉及3种结构:

页目录:一个数组,最多可包含1024个32位页目录项。

页表:一个数组,最多可包含1024个32位页表项。

页:4KB或4MB的地址空间。

31.哪种结构包含了页表的基地址?

答:页表项结构包含了页表的基地址。

32.哪种结构包含了页面的基地址?

答:页项结构包含了页面的基地址。

11.7.2算法基础

1.编写代码段调用函数ReadConsole。

;11.7.2_ReadConsole.asm      11.7.2 算法基础
;1.编写代码段调用函数ReadConsole。;本程序调用如下win32控制台函数:
;GetstdHandle,ExitProcess、ReadConsole
INCLUDE Irvine32.inc
BufSize = 80.data
buffer BYTE BufSize DUP(?),0,0
stdInHandle HANDLE ?
bytesRead DWORD ?				 .code 
main PROC;获得标准输入句柄:INVOKE GetStdHandle, STD_INPUT_HANDLEmov stdInHandle, eax;等待用户输入INVOKE ReadConsole, stdInHandle,			;控制台输入句柄ADDR buffer,			;缓冲区地址BufSize,				;缓冲区大小ADDR bytesRead,			;读取的实际数大小0						;未使用;显示缓冲区mov esi, OFFSET buffermov ecx, bytesReadmov ebx, TYPE buffercall DumpMemINVOKE ExitProcess, 0
main ENDP 
END main

运行调试:

2.编写代码段调用函数WriteConsole。

;11.7.2_WriteConsole.asm      11.7.2 算法基础
;2.编写代码段调用函数WriteConsole。;本程序调用如下win32控制台函数:
;GetstdHandle,ExitProcess、WriteConsole
INCLUDE Irvine32.inc.data
endl EQU <0dh, 0ah>					;行结尾
message LABEL BYTEBYTE "Electronic versions of these documents allow you to quickly "BYTE "get the information you need and print only the pages you want. ", endl
messageSize DWORD ($ - message)
stdOutHandle HANDLE 0				;标准输出设备句柄
bytesWritten DWORD ?				;输出字节数.code 
main PROC;获得标准输出句柄:INVOKE GetStdHandle, STD_OUTPUT_HANDLEmov stdOutHandle, eax;等待用户输入INVOKE WriteConsole, stdOutHandle,			;控制台输出句柄ADDR message,			;字符串指针 messageSize,			;字符长度ADDR bytesWritten,		;返回输出字节数0						;未使用mov esi, OFFSET messagemov ebx, bytesWrittenINVOKE ExitProcess, 0
main ENDP 
END main

运行调试:

3.编写代码段调用函数 CreateFile 打开已有文档以便读出。

;11.7.2_CreateFile_ReadFile.asm      11.7.2 算法基础
;3.编写代码段调用函数 CreateFile 打开已有文档以便读出。;本程序调用如下win32控制台函数:
;CreateFile,ExitProcess、ReadFile
INCLUDE Irvine32.inc.data
flName BYTE "aaa.txt"				;文件名
fileHandle HANDLE 0					;文件句柄
str1 BYTE "CreateFile OPEN ERROR.", 0
readBuffer BYTE 80 DUP(?), 0
readSize = 64
realSize DWORD ?.code 
main PROC;打开并读取已存在文件INVOKE CreateFile,ADDR flName,				;文件名指针GENERIC_READ,				;读文件DO_NOT_SHARE,				;共享模式NULL,						;安全属性指针OPEN_EXISTING,				;打开已存在文件FILE_ATTRIBUTE_NORMAL,		;普通文件属性0							;未使用mov fileHandle, eax;错误检查cmp eax, INVALID_HANDLE_VALUE	;发现错误?jne file_ok						;否:跳过mov edx, OFFSET str1			;显示错误call WriteStringjmp quitfile_ok:;读取文件内容INVOKE ReadFile,fileHandle,					;文件句柄ADDR readBuffer,			;缓冲区指针readSize,					;读取的字节数ADDR realSize,				;实际读取的字节数0							;异步信息指针mov edx, OFFSET readBuffer		call WriteString				;显示读取文件的内容quit:call CrlfINVOKE ExitProcess, 0
main ENDP 
END main

运行调试,打开已存在的文件:

读取文件内容

4.编写代码段调用函数 CreateFile 用标准属性新建一个文档,并删除其他已存在的同名文件。

;11.7.2_CreateFile_DeleteExist.asm      11.7.2 算法基础
;4.编写代码段调用函数 CreateFile 用标准属性新建一个文档,并删除其他已存在的同名文件。;本程序调用如下win32控制台函数:
;CreateFile,ExitProcess、WriteString
INCLUDE Irvine32.inc.data
flName BYTE "aaa.txt"				;文件名(已存在的文件)
fileHandle HANDLE 0					;文件句柄
str1 BYTE "CreateFile OPEN ERROR.", 0
str2 BYTE "File creation successful, overwrite existing files", 0.code 
main PROC;打开并删除已存在文件INVOKE CreateFile,ADDR flName,				;文件名指针GENERIC_WRITE,				;写文件DO_NOT_SHARE,				;共享模式NULL,						;安全属性指针CREATE_ALWAYS,				;覆盖已存在的文件FILE_ATTRIBUTE_NORMAL,		;普通文件属性0							;未使用mov fileHandle, eax;错误检查cmp eax, INVALID_HANDLE_VALUE	;发现错误?jne file_ok						;否:跳过mov edx, OFFSET str1			;显示错误call WriteStringjmp quitfile_ok:mov edx, OFFSET str2			;覆盖已存在的文件		call WriteString				;显示文件创建成功quit:call CrlfINVOKE ExitProcess, 0
main ENDP 
END main

运行调试:

5.编写代码段调用函数 ReadFile。

;11.7.2_ReadFile.asm      11.7.2 算法基础
;5.编写代码段调用函数 ReadFile。;本程序调用如下win32控制台函数:
;CreateFile,ExitProcess、ReadFile
INCLUDE Irvine32.inc.data
flName BYTE "aaa.txt"				;文件名
fileHandle HANDLE 0					;文件句柄
str1 BYTE "CreateFile OPEN ERROR.", 0
readBuffer BYTE 80 DUP(?), 0
readSize = 70
realSize DWORD ?.code 
main PROC				;打开并读取已存在文件INVOKE CreateFile,ADDR flName,				;文件名指针GENERIC_READ,				;读文件DO_NOT_SHARE,				;共享模式NULL,						;安全属性指针OPEN_EXISTING,				;打开已存在文件FILE_ATTRIBUTE_NORMAL,		;普通文件属性0							;未使用mov fileHandle, eax;错误检查cmp eax, INVALID_HANDLE_VALUE	;发现错误?jne file_ok						;否:跳过mov edx, OFFSET str1			;显示错误call WriteStringjmp quitfile_ok:;读取文件内容INVOKE ReadFile,fileHandle,					;文件句柄ADDR readBuffer,			;缓冲区指针readSize,					;读取的字节数ADDR realSize,				;实际读取的字节数0							;异步信息指针mov edx, OFFSET readBuffer		call WriteString				;显示读取文件的内容call Crlf;读取的字节数mov eax, readSizecall WriteDeccall Crlf;实际读取的字节数mov eax, realSizecall WriteDecquit:call CrlfINVOKE ExitProcess, 0
main ENDP 
END main

运行调试:

6.编写代码段调用函数 WriteFile。

;11.7.2_WriteFile.asm      11.7.2 算法基础
;6.编写代码段调用函数 WriteFile。;本程序调用如下win32控制台函数:
;CreateFile,ExitProcess、WriteFile
INCLUDE Irvine32.inc.data
flName BYTE "aaa.txt"				;文件名
fileHandle HANDLE 0					;文件句柄
str1 BYTE "CreateFile OPEN ERROR.", 0
writeBuffer BYTE "can be customized using style sheets", 0
bufferSize = 38
realSize DWORD ?.code 
main PROC;打开并读取已存在文件INVOKE CreateFile,ADDR flName,				;文件名指针GENERIC_WRITE,				;写文件DO_NOT_SHARE,				;共享模式NULL,						;安全属性指针CREATE_ALWAYS,				;若文件存在,覆盖文件FILE_ATTRIBUTE_NORMAL,		;普通文件属性0							;未使用mov fileHandle, eax;错误检查cmp eax, INVALID_HANDLE_VALUE	;发现错误?jne file_ok						;否:跳过mov edx, OFFSET str1			;显示错误call WriteStringjmp quitfile_ok:;写入文件内容INVOKE WriteFile,fileHandle,					;文件句柄ADDR writeBuffer,			;缓冲区指针bufferSize,					;缓冲区大小ADDR realSize,				;写入字节数0							;异步信息指针mov eax, realSize		call WriteDec					;显示写入的字节数quit:call CrlfINVOKE ExitProcess, 0
main ENDP 
END main

运行调试:

7.编写代码段调用函数 MessageBox。

;11.7.2_WriteFile.asm      11.7.2 算法基础
;7.编写代码段调用函数 MessageBox。INCLUDE Irvine32.inc.data
captionW		BYTE "Warning", 0
warningMsg		BYTE "The current operation may take years "BYTE "to complete.", 0
captionQ		BYTE "Question", 0
questionMsg		BYTE "A matching user account was not found."BYTE 0dh, 0ah, "Do you wish to continue?", 0
captionC		BYTE "Information", 0
infoMsg			BYTE "Select Yes to save a backup file "BYTE "before continuing,", 0dh, 0ahBYTE "or click Cancel to stop the operation", 0
captionH		BYTE "Cannot View User List", 0
haltMsg			BYTE "This operation not supported by your "BYTE "user account.", 0.code 
main PROC;显示感叹号图标和OK按钮INVOKE MessageBox, NULL, ADDR warningMsg,ADDR captionW,MB_OK + MB_ICONEXCLAMATION;显示问号图标和Yes/No按钮INVOKE MessageBox, NULL, ADDR questionMsg,ADDR captionQ, MB_YESNO + MB_ICONQUESTION;解释用户点击的按钮cmp eax, IDYES					;点击的是Yes按钮吗?;显示信息图标和Yes/No/Cancel按钮INVOKE MessageBox, NULL, ADDR infoMsg,ADDR captionC, MB_YESNOCANCEL + MB_ICONINFORMATION + MB_DEFBUTTON2;显示停止图标和OK按钮INVOKE MessageBox, NULL, ADDR haltMsg,ADDR captionH, MB_OK + MB_ICONSTOPINVOKE ExitProcess, 0
main ENDP 
END main

运行调试:

显示问号图标和Yes/No按钮

显示信息图标和Yes/No/Cancel按钮

显示停止图标和OK按钮

http://www.xdnf.cn/news/17109.html

相关文章:

  • uiautomator2 编写测试流程-登陆后的酷狗01
  • 进程生命周期管理:从创建到终止的完整逻辑
  • 探索医学领域多模态人工智能的发展图景:技术挑战与临床应用的范围综述|文献速递-医学影像算法文献分享
  • iOS 内测上架流程详解:跨平台团队如何快速部署 TestFlight
  • 注解知识学习
  • 凹槽类零部件尺寸的检测方法有哪些 - 激光频率梳 3D 轮廓检测
  • [硬件电路-156]:什么是电信号? 电信号的本质:电信号是随时间变化的电压或电流。本质是电子运动表征信息,兼具能量传输与信息编码传递功能。
  • Mac电脑基本功能快捷键
  • EdgeView for macOS:解决图像管理痛点的利器
  • 设计模式 -> 策略模式(Strategy Pattern)
  • 经典设计模式
  • 验证码等待时间技术在酒店自助入住、美容自助与社区场景中的应用必要性研究—仙盟创梦IDE
  • Calcite自定义扩展SQL案例详细流程篇
  • 六、Linux核心服务与包管理
  • 前端 拼多多4399笔试题目
  • [自动化Adapt] 录制引擎 | iframe 穿透 | NTP | AIOSQLite | 数据分片
  • Connection refused: no further information: localhost/127.0.0.1:2375
  • 第四章:OSPF 协议
  • ssh服务器端口和本地端口映射
  • [spring-cloud: 服务发现]-源码解析
  • 旧笔记本电脑如何安装飞牛OS
  • 电商系统定制开发流程:ZKmall开源商城需求分析到上线全程可控
  • MySQL深度理解-MySQL锁机制
  • 【Mysql】日志--错误日志、二进制日志、查询日志、慢查询日志
  • Shell脚本-变量的定义规则
  • LLM调研
  • 【QT】概述
  • Azure DevOps — Kubernetes 上的自托管代理 — 第 4 部分
  • 微分方程模型:用“变化率”的语言,描绘世间万物的动态演化
  • 前端面试手撕题目全解析