《汇编语言 基于x86处理器》第十一章 MS-DOS 编程部分的代码 part 2

? 书中第十一章的程序,主要讲了 Windows 接口,在小黑框中进行程序交互

● 在屏幕指定位置输出带自定义属性的文字

 1 INCLUDE Irvine32.inc
 2
 3 .data
 4 outHandle    HANDLE ?
 5 cellsWritten DWORD ?        ; 输出计数(输出参数)
 6 xyPos COORD <10,2>          ; 输出坐标
 7 buffer BYTE 41h,42h,43h,44h,45h,46h,47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,4Fh,50h,51h,52h,53h,54h
 8 BufSize DWORD ($ - buffer)
 9 attributes WORD 1h,2h,3h,4h,5h,6h,7h,8h,9h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,10h,11,12h,13h,14h
10
11 .code
12 main PROC
13     INVOKE GetStdHandle, STD_OUTPUT_HANDLE
14     mov outHandle, eax
15     INVOKE WriteConsoleOutputAttribute, outHandle, ADDR attributes, BufSize, xyPos, ADDR cellsWritten   ; 设置输出属性
16     INVOKE WriteConsoleOutputCharacter, outHandle, ADDR buffer, BufSize, xyPos, ADDR cellsWritten       ; 输出
17
18     call ReadChar
19     ;call WaitMsg   ; 与 ReadChar 等效
20     exit
21 main ENDP
22 END main

● 动态内存分配 1

 1 INCLUDE Irvine32.inc
 2
 3 .data
 4 ARRAY_SIZE = 1000       ; 要申请的数组尺寸
 5 FILL_VAL EQU 0FFh       ; 数组填充的值
 6
 7 hHeap   DWORD ?
 8 pArray  DWORD ?         ; 堆内存指针
 9 str1 BYTE "Heap size is: ",0
10
11 .code
12 main PROC
13     INVOKE GetProcessHeap      ; 获取堆内存的指针
14     .IF eax == NULL
15         call    WriteWindowsMsg
16     jmp quit
17     .ELSE
18         mov     hHeap, eax
19     .ENDIF
20
21     call    allocate_array
22     jnc     arrayOk             ; 申请成功 CF = 0,失败 CF = 1
23     call    WriteWindowsMsg
24     call    Crlf
25     jmp     quit
26
27 arrayOk:                        ; 填充和输出数组
28     call    fill_array
29     call    display_array
30     call    Crlf
31
32     INVOKE HeapFree, hHeap, 0, pArray   ; 释放申请的内存
33
34 quit:
35     call WaitMsg
36     exit
37 main ENDP
38
39 allocate_array PROC USES eax            ; 申请堆内存
40     INVOKE HeapAlloc, hHeap, HEAP_ZERO_MEMORY, ARRAY_SIZE
41
42     .IF eax == NULL
43        stc                ; 申请失败,置 CF = 1
44     .ELSE
45        mov  pArray,eax    ; 申请成功,保存内存指针,置 CF = 0
46        clc
47     .ENDIF
48
49     ret
50 allocate_array ENDP
51
52 fill_array PROC USES ecx edx esi
53     mov    ecx, ARRAY_SIZE
54     mov    esi, pArray
55
56 L1:
57     mov    BYTE PTR [esi], FILL_VAL
58     inc    esi
59     loop    L1
60
61     ret
62 fill_array ENDP
63
64 display_array PROC USES eax ebx ecx esi
65     mov    ecx, ARRAY_SIZE
66     mov    esi, pArray
67
68 L1:
69     mov    al, [esi]
70     mov    ebx, TYPE BYTE
71     call    WriteHexB
72     inc    esi
73     loop    L1
74
75     ret
76 display_array ENDP
77
78 END main

● 动态内存分配 2,申请多个内存堆,直到溢出

 1 INCLUDE Irvine32.inc
 2
 3 .data
 4 HEAP_START =    2000000     ;   2 MB
 5 HEAP_MAX   =  400000000     ; 400 MB
 6 BLOCK_SIZE =     500000     ;  .5 MB
 7
 8 hHeap DWORD ?
 9 pData DWORD ?
10
11 str1 BYTE 0dh,0ah,"Memory allocation failed",0dh,0ah,0
12
13 .code
14 main PROC
15     INVOKE HeapCreate, 0,HEAP_START, HEAP_MAX
16
17     .IF eax == NULL         ; 申请失败
18     call    WriteWindowsMsg
19     call    Crlf
20     jmp     quit
21     .ELSE                   ; 申请成功
22     mov     hHeap, eax
23     .ENDIF
24
25     mov     ecx, 2000
26
27 L1:
28     call allocate_block     ; 申请内存堆
29     .IF Carry?              ; 失败
30     mov     edx,OFFSET str1
31     call    WriteString
32     jmp     quit
33     .ELSE                   ; 成功,
34     mov     al,‘.‘          ; 输出一个点
35     call    WriteChar       ; 显示进度
36     .ENDIF
37
38     ;call free_block        ; 是否把刚申请的堆释放掉
39     loop    L1
40
41 quit:
42     INVOKE HeapDestroy, hHeap   ; 释放掉所有的堆
43     .IF eax == NULL             ; 失败则显示信息
44     call    WriteWindowsMsg
45     call    Crlf
46     .ENDIF
47
48     exit
49 main ENDP
50
51 allocate_block PROC USES ecx
52     INVOKE HeapAlloc, hHeap, HEAP_ZERO_MEMORY, BLOCK_SIZE
53
54     .IF eax == NULL
55     stc                     ; 失败,置 CF = 1
56     .ELSE
57     mov     pData,eax       ; 成功,指针保存到 eax
58     clc                     ; 置 CF = 0
59     .ENDIF
60
61     ret
62 allocate_block ENDP
63
64 free_block PROC USES ecx
65     INVOKE HeapFree, hHeap, 0, pData
66     ret
67 free_block ENDP
68
69 END main

● 文件读写(有点问题,尚未完成)

 1 INCLUDE Irvine32.inc
 2 INCLUDE macros.inc
 3
 4 BUFFER_SIZE = 500
 5
 6 .data
 7 buffer BYTE "abcdef", 0
 8 filename     BYTE "output.txt", 0
 9 fileHandle   HANDLE ?
10 stringLength DWORD ?
11 bytesWritten DWORD ?
12
13 .code
14 main PROC
15
16     mov     edx, OFFSET filename
17     call    CreateOutputFile
18     mov     fileHandle, eax
19     cmp     eax,  INVALID_HANDLE_VALUE  ; 错误检查
20     jne     file_ok1
21     mWrite <"Failed to create output file",0dh,0ah>
22     jmp     quit
23
24 file_ok1:
25     mov     eax, fileHandle         ; 写入文件
26     mov     edx, OFFSET buffer
27     mov     ecx, SIZEOF buffer
28     call    WriteToFile
29     mov     bytesWritten, eax       ; 返回写入字符串长度
30     call    CloseFile
31
32     mWrite  <"Bytes written to file [output.txt]: "> ; 显示写入字符串长度
33     mov     eax, bytesWritten
34     call    WriteDec
35     call    Crlf
36     call    WaitMsg
37
38     mov     eax, SIZEOF filename        ; 打开文件
39     mov     edx, OFFSET filename
40     call    OpenInputFile
41     mov     fileHandle, eax
42
43     cmp     eax, INVALID_HANDLE_VALUE   ; 错误检查
44     jne     file_ok2
45     mWrite  <"Failed to open the file",0dh,0ah>
46     jmp     quit
47
48 file_ok2:
49     mov     edx, OFFSET buffer            ; 读取文件
50     mov     ecx, BUFFER_SIZE
51     call    ReadFromFile
52     jnc     check_buffer_size
53     mWrite  <"Failed to read the file.", 0dh, 0ah>
54     call    WriteWindowsMsg
55     jmp     close_file
56
57 check_buffer_size:                          ; 检查是否超出缓冲区大小
58     cmp     eax, BUFFER_SIZE
59     jb      buf_size_ok
60     mWrite  <"Failed to read the file into buffer", 0dh, 0ah>
61     jmp     quit
62
63 buf_size_ok:
64     mov     buffer[eax],0        ; insert null terminator
65     mWrite  "File size: "
66     call    WriteDec            ; display file size
67     call    Crlf
68
69     mWrite <"Buffer:",0dh,0ah,0dh,0ah>
70     mov    edx,OFFSET buffer    ; display the buffer
71     call    WriteString
72     call    Crlf
73
74 close_file:
75     mov     eax, fileHandle
76     call    CloseFile
77
78 quit:
79     call    WaitMsg
80     exit
81 main ENDP
82 END main

原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9741651.html

时间: 2024-10-12 14:39:42

《汇编语言 基于x86处理器》第十一章 MS-DOS 编程部分的代码 part 2的相关文章

《汇编语言 基于x86处理器》第九章字符串与数组部分的代码

? 书中第九章的程序,主要讲了 ● 代码,Irvine32 中的字符串库函数代码范例 1 INCLUDE Irvine32.inc 2 3 .data 4 str1 BYTE "abcde////", 0 5 str2 BYTE "ABCDE", 0 6 msg0 BYTE "Upper case: ", 0 7 msg1 BYTE "str1 == str2", 0 8 msg2 BYTE "str1 < s

《汇编语言 基于x86处理器》第十章结构和宏部分的代码

? 书中第十章的程序,主要讲了结构与宏的使用 ● 代码,使用结构,对比是否对齐的性能差距 1 INCLUDE Irvine32.inc 2 INCLUDE macros.inc 3 4 structN STRUCT ; 非对齐的结构 5 Lastname BYTE 30 DUP(0) ; 30 6 Years WORD 0 ; 2 7 SalaryHistory DWORD 0, 0, 0, 0 ; 16 8 structN ENDS ; 48 Byte 9 10 structA STRUCT

《汇编语言 基于x86处理器》第十三章高级语言接口部分的代码 part 1

? 书中第十三章的程序,主要讲了汇编语言和 C/++ 相互调用的方法 ● 代码,数组求和的几种优化 1 int arraySum(int array[], int count) ; O0 2 { 3 010716D0 push ebp 4 010716D1 mov ebp,esp 5 010716D3 sub esp,0D8h 6 010716D9 push ebx 7 010716DA push esi 8 010716DB push edi 9 010716DC lea edi,[ebp-0

汇编语言:基于 X86 处理器第三章复习笔记

一:基本语言元素 1:整数常量 整数常量表达式:[{ + / - }] digits [ radix ] 整数常量的表达与进制是分不开的,通常通过在尾部添加字母加以区分: 十六进制 h 十进制   t(一般省略) 八进制   o/q 二进制   b 编码实数 r 注意:以字母开头的十六进制为了与标识符分区,必须在前面加数字 0 2:整形常量表达式 整形常量表达式是指一种算术表达式,由整数常量,算术运算符构成,注意:整形常量表达式的运算结果也必须是一个整数常量,其位数应该在处理器的位数之内 算术表

第8章防范式编程下(代码大全4)

8.4 Exceptions 异常 用异常通知程序的其他部分,发生了不可忽略的错误 只在真正例外的情况下才抛出异常 不能用异常来推卸责任 避免在构造函数和析构函数中抛出异常,除非你在同一地方把它们捕获 在恰当的抽象层次抛出异常 在异常消息中加入关于导致异常发生的全部信息 避免使用空的catch语句 了解所用函数库可能抛出的异常 考虑创建一个集中的异常报告机制 把项目中对异常的使用标准化 对于像C++这类语言,其中允许抛出多种多样的对象.数据及指针的话,那么就应该为到底可以抛出哪些类的异常建立一个

第8章防范式编程上(代码大全3)

防御式编程并不是说让你在编程时持“防备批评或攻击”的态度——“它就是这么工作!”这一概念来自防御式驾驶.在防御式驾驶中要建立这样一种思维,那就是你永远也不能确定另一位司机将要做什么.这样才能确保其他人在做出危险动作时你也不会受到伤害.你要担负起保护自己的责任,哪怕是其他司机犯的错误.防御式编程的主要思想是:子程序应该不因为传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据.更一般地说,其核心是要承认程序都会有问题,都需要被修改,聪明的程序员应该根据这一点来编程序. 8.1 Protectin

[CSAPP笔记][第十一章网络编程]

第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真实的Web浏览器提供静态的和动态的文本和图形内容. 11.1 客户端 - 服务器编程模型 每个网络应用程序都是基于客户端 - 服务器模型的 采用这种模型,一个应用是由一个服务器进程 和一个或多个客户端进程组成. 服务器管理某种资源,并且通过操作这种资源为它的客户端提供某种服务. WEB服务器,代表客

Android研究之为基于 x86 的 Android* 游戏选择合适的引擎详解

摘要 游戏开发人员知道 Android 中蕴藏着巨大的机遇. 在 Google Play 商店的前 100 款应用中,约一半是游戏应用(在利润最高的前 100 款应用中,它们所占的比例超过 90%). 如要跻身该市场,开发速度非常关键. 一些刚起步的独立开发人员更愿意从零开始来开发自己的所有代码:但是为了达到更高的质量而不用花费数年的时间进行开发,其他人可能会选择已有的游戏引擎.上章研究了英特尔 Android* 开发人员指南上的对等应用详解,在选择引擎时,你可以考虑以下几个因素: 成本 - 你

javascript高级程序设计 第十一章--DOM扩展

javascript高级程序设计 第十一章--DOM扩展DOM最主要的扩展就是选择符API.HTML5和Element Traversal Selectors API:定义了两个方法 querySelector() 和 querySelectorAll(),能够基于CSS选择符从DOM中取得元素.querySelector()方法接收一个CSS选择符,返回该模式匹配的第一个元素,querySelectorAll()接收的参数一样,但是返回NodeList实例: matchesSelector()