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

Posted cuancuancuanhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《汇编语言 基于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

 

以上是关于《汇编语言 基于x86处理器》第十一章 MS-DOS 编程部分的代码 part 2的主要内容,如果未能解决你的问题,请参考以下文章

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

构建之法第十一章读后感

第十一章:使用数据处理函数

第十一章 使用数据处理函数

第十一章

2017.06.29数据挖掘基础概念第十,十一章