1局部可以JMP全局的 反之不行
2过程
3在保存和恢复寄存器时候,在过程 使用寄存器做返回值时候内部能将返回值的寄存器压栈或弹出
设置环境变量
INCLUDE(C:/MASM615/INCLUDE) , LIB(C:/MASM615/LIB),PATH(C:/MASM615)
ml /c /coff msgbox.asmlink /subsystem:windows msgbox.obj irvine32.lib kernel32.lib user32.lib
缺少DLL文件 安装下
《Intel汇编语言程序设计》一书的例程,需要首先进行环境配置。到下载“MASM615”注意是网络上的人搜集起和这书配套的工具。安装或者解压到C:/masm615运行CMD,输入set lib c:/masm615set include c:/masm615/includeset path c:/masm615,%path%这是初步的环境搭建在编程时,在例程的源码里加上以下内容include irvine32.incincludelib kernel32.libincludelib irvine32.lib然后编译,在CMD中进入存放.asm文件的目录然后ml /c /coff /i xxx.asm 如果这句不行,去掉/ilink32 /subsystem:(这里必须注意选择,冒号后填console是命令行程序,windows是窗口程序) xxx.obj
1 windows 程序
.386.model flat,stdcalloption casemap:none ; 这句是区分大小写,因为api是区分大小写的include user32.incincludelib user32.libinclude kernel32.incincludelib kernel32.libinclude smallwin.inc
2控制台程序
就不需要以上的
本书1-10章就需要
INCLUDE Irvine32.inc
第一种 Irvine32.inc 没有MsgBox函数需要自己写
.386 .model flat,stdcall option casemap:none include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib .data caption db "Dialog Title" , 0 HelloMsg BYTE "This is a pop-up message box." , 0dh , 0ah BYTE "Click OK to continue......" , 0 .code MsgBox PROC invoke MessageBox,NULL,edx,ebx,MB_OK ret MsgBox endp main proc mov ebx , OFFSET caption mov edx , OFFSET HelloMsg call MsgBox INVOKE ExitProcess,0 main endp END main
第二种Irvine32.inc 含有MsgBox函数(书中的使用的Irvine32.inc链接库和每章例题源码.rar)
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data caption db "Dialog Title", 0 HelloMsg BYTE "This is a pop-up message box.", 0dh,0ah BYTE "Click OK to continue...", 0 .code main PROC mov ebx,0 ; no caption mov edx,OFFSET HelloMsg ; contents call MsgBox mov ebx,OFFSET caption ; caption mov edx,OFFSET HelloMsg ; contents call MsgBox exit main ENDP END main
1 .CreateOutputFile eax传创建文件名的偏移地址 CMP 和JE 第6章讲到
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data filename BYTE "newfile.txt",0 .code main PROC mov edx,OFFSET filename call CreateOutputFile cmp eax,INVALID_HANDLE_VALUE exit main ENDP END main
2 控制台程序 DumpMem 显示内存 DumpRegs显示寄存器
ml /c /coff du.asm
link /subsystem:windows msgbox.obj irvine32.lib kernel32.lib user32.lib
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data array DWORD 1,2,3,4,5,6,7,8,9,0ah,0bh .code main PROC mov esi,OFFSET array ;起始地址 mov ecx,LENGTHOF array ;元素数目 mov ebx,type array ;格式为双字 call DumpMem call DumpRegs exit main ENDP END main
3 GetMaxXY DL 放窗口缓冲区的烈数,DH放窗口缓冲区的行数
行数和烈数 为255 超过了这个大小 控制台窗口会自动出现滚动条
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data rows BYTE ? cols BYTE ? .code main PROC call GetMaxXY mov rows,dh mov cols,dl exit main ENDP END main
4 GetMseconds 返回从午夜开始计算的失去的毫秒数,返回到EAX中,
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data startTime DWORD ? .code main PROC call GetMseconds mov startTime,eax L1: ;(循环体) loop L1 call GetMseconds sub eax,startTime call DumpRegs exit main ENDP END main
5 GetTextColor 返回控制台窗口的前景和背景色
AL 为16进制的 转化为二进制 前4位为背景色,低4位为前景色
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data color BYTE ? .code main PROC call GetTextColor mov color,AL mov esi,OFFSET color ;起始地址 mov ecx,LENGTHOF color ;元素数目 mov ebx,type color ;格式为双字 call DumpMem call DumpRegs exit main ENDP END main
6 Gotoxy 定位光标 DX显示行列
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .code main PROC mov dh,10 ;行10 mov dl,20 ;列20 call Gotoxy ;定位光标 exit main ENDP END main
7 是否为10进制数
8 是否有按键
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data color BYTE ? .code main PROC call GetTextColor mov color,AL mov esi,OFFSET color ;起始地址 mov ecx,LENGTHOF color ;元素数目 mov ebx,type color ;格式为双字 call DumpMem call DumpRegs exit main ENDP END main
9 有多少个字符
TITLE MsgBox demo (msgbox.asm) INCLUDE Irvine32.inc .data buffer BYTE "abcde",0 bufLength DWORD ? .code main PROC mov edx,OFFSET buffer call StrLength mov bufLength,eax call DumpRegs exit main ENDP END main
屏幕显示和光标的变换
– Clrscr:用于清除控制台窗口内容 – Crlf:将光标定位到控制台窗口下一行的开始 – Gotoxy:将光标定位在控制台窗口中指定的行列位置上。 默认情况下,X坐标范围(列坐标):0~79,设置在DL中;Y坐标范围(行坐标):0~24,设置在DH中 例如: mov dh, 10 mov dl, 20 call gotoxyl 关于时间 – Delay:以指定的毫秒数暂停程序;EAX设置为预期时间间隔,单位是毫秒。例如: mov eax, 1000 call delay – GetMseconds:从午夜开始计算的逝去的毫秒数;返回值在EAX中。 .data startTime DWORD ? .code call GetMseconds mov startTime, eax L1: … ;(循环体) loop L1 call GetMseconds sub eax, startTime – WaitMsg:显示 “Press [Enter] to continue …”消息,并等待用户按下回车键。 – MsgBox:显示一个图形界面的弹出消息框。调用时可以通过EDX传递要显示的字符串的偏移地址,字符串将显示在消息框中央,还可以通过EBX传递要显示在标题栏中的字符串的偏移地址。 – MsgBoxAsk:显示一个带Yes和NO按钮图形界面的弹出消息框。调用时通过EDX传递要显示的作为问题的字符串的偏移地址,EBX传递要显示在标题栏中的字符串的偏移地址。 MsgBoxAsk在EAX中返回一个整数值:IDYES和IDNO,通过该返回值可以知道用户选择了哪个按钮。 l 从标准输入读入 – ReadChar:读取一个字符并在AL中返回,输入的字符不在屏幕上回显。 – ReadHex:读取一个32位十六进制整数并在EAX寄存器中返回、过程对无效字符不进行错误检查。 – ReadInt:读入一个32位有符号整数、EAX、用户可以在前面输入正负号,其余部分只能是数字,进行错误检查。 – – ReadDec:读取一个无符号32位十进制整数并在EAX中返回。 ReadDec对进位标志的影响如下: 如果输入的整数字符串为空,则EAX=0, CF=1 如果输入的整数字符串只包含空格,则EAX=0, CF=1 如果输入的整数大于232-1,则EAX=0, CF=1 除上述情况之外,EAX=转换后的整数, CF=0 l 从标准设备输出 – WriteBin:以ASCII码的二进制格式显示EAX中的整数。 – WriteChar:显示一个字符、调用之前需将字符存储在AL中。 – WriteDec:以十进制格式显示一个32位无符号整数,输出的数字开头不带0,调用之前,需将整数保存在EAX中。 – WriteHex:以十六进制格式显示一个32位无符号整数、格式是以8个十六进制的数据位表示,调用之前存入EAX中。 – WriteInt:以十进制格式显示一个32位有符号整数、输出的数字开头没有0,但有符号位,调用之前存入EAX中。 – l 生成随机数 – Randomsize:初始化在Random32和RandomRange过程的随机数公式中使用的种子值。保证在每次运行程序时,产生的初始随机数都不同。 – Random32:生成32位的随机整数并在EAX中返回。 – RandomRange:生成一个0~(n-1)之间的随机整数,其中n是通过EAX传递的参数,生成的随机数在EAX中返回。例如:下面的语句生成一个0~4999之间的随机整数并存放在EAX中。 .data randval DWORD ? .code mov eax, 5000 call RandomRange mov randval , eax – DumpMem:以十六进制格式显示一块内存的内容。在调用之前,需要将ESI设置为内存开始地址,ECX设置为元素数目,EBX设置为元素尺寸(1=byte, 2=word, 4=doubleword)。 例如:显示一个名为array的包含11个双字变量的数组。 .data array DWORD 1, 2, 3, 4, 5, 6, 7, 8, 9, 0AH, 0BH .code main proc mov esi, offset array mov ecx, lengthof array mov ebx, type array call dumpmem WriteString:显示一个以空字符结尾的字符串,调用之前,将欲显示的字符串的偏移存放在EDX中 ReadString:读取一个字符串,并在用户按下回车键时停止。EAX中返回字符数、在调用之前,需要将EDX设置为指向保存输入字符串的偏移地址、同时将ECX设置为最多可读入的字符数。P113 MOV ECX, (SIZEOF buffer)-1
– DumpRegs:以十六进制格式显示CPU通用寄存器、EFLAGS、EIP的内容,并同时显示CF、SF、ZF、OF标志。显示的EIP值是紧跟在call DumpRegs语句后面的指令的偏移地址。 – GetCommandTail:将程序的命令行拷贝到一个以空字符结尾的字符串中。如果命令行为空,则设置进位标志,否则清除进位标志。 – GetTextColor:返回当前控制台窗口的前景和背景色。返回值在AL中,高4位是背景色,低4位是前景色。 – mov eax,white+(blue*16) ;蓝底白字 call SetTextColor – CloseFile:关闭一个已经打开的文件。文件是以文件句柄标识的,文件句柄通过EAX传递。如果文件被成功关闭,EAX中返回值为非零值。 – CreatOutputFile:创建一个磁盘文件并以输出模式打开。通过EDX传递要创建的文件名的偏移地址。过程返回时,如果文件创建成功,则EAX包含有效的文件句柄。如果创建失败,EAX中的值是INVALD_HANDLE_VALUE。 – OpenInputFile:打开一个已存在的磁盘文件以进行输入。通过EDX传递要打开的文件名的偏移地址。 – – GetMaxXY:返回控制台窗口缓冲区的大小。无输入参数,返回时,DL存放窗口缓冲区的列数,DH存放窗口缓冲区的行数。 – IsDigit:确定AL中的字符是否是有效的十进制数字(0~9)。调用该过程时通过AL传递ASCII字符。如果AL中的字符是有效的十进制数字,则零标志置位,否则零标志清零。 mov AL, somechar call IsDigit jz digit_found – ParseDecimal32:把无符号整数字符串转换为一个32位的二进制数。EDX传递字符串的偏移地址,ECX传递字符串的长度,转换后的二进制值在EAX中返回。 – ParseInteger32:把有符号整数字符串转换为一个32位的二进制数。字符串开头可以有符号字符:加号(表示正数)或负号(表示负数),但符号后必须跟十进制数字。
库测试程序
include Irvine32.inc .data arrayD DWORD 1000h,2000h,3000h prompt1 BYTE "Enter a 32-bit signed integer:",0 dwordVa1 DWORD ? .code main proc mov eax,yellow+(blue*16);; call SetTextColor ;; 设置兰背景 黄字 call Clrscr ;; mov esi,OFFSET arrayD ;; mov ecx,LENGTHOF arrayD ;; mov ebx,TYPE arrayD ;; call DumpMem ;; 以上使用DumpMem过程显示数组的内容 call Crlf ;清除屏幕 ; main endp END main
完整的程序
TITLE Library Test #1:Integer I/O (TestLib1.asm) INCLUDE Irvine32.inc .data arrayD DWORD 1000h,2000h,3000h prompt1 BYTE "Enter a 32-bit signed integer:",0 dwordVal DWORD ? .code main PROC mov eax, yellow+(blue*16) call setTextColor call clrscr mov esi, offset arrayD mov ecx, lengthof arrayD mov ebx, TYPE arrayD call DumpMem call Crlf call Crlf ;换行 ;提示请输入一个10进制数 mov edx,OFFSET prompt1 ; call WriteString ;显示 请输入》》》 call ReadInt ;输入整数 mov dwordVa1,EAX ;保存到变量中 ;以10,16和2进制显示 call Crlf ; call WriteInt ; call Crlf ; call WriteHex ; call Crlf ; call WriteBin ; call Crlf ; call WaitMsg ; ;将控制台窗口设置默认颜色 mov eax,lightGray+(black*16) call SetTextColor call Clrscr ;清除窗口 exit main ENDP END main
第2 随机整数
TITLE Link Library Test #2 (TestLib2.asm) INCLUDE Irvine32.inc TAB=9 ;Tab键的ASCII码 .code main PROC call Randomize call Rand1 ;call Rand2 exit main ENDP Rand1 PROC mov ecx,10 L1: call Random32 call WriteDec mov al, TAB call WriteChar loop L1 call Crlf ret Rand1 ENDP Rand2 PROC mov ecx,10 L1: call RandomRange sub eax,50 call WriteInt mov al, TAB call WriteChar loop L1 call Crlf ret Rand2 ENDP END main
第3 性能度量
TITLE Link Library Test #3(TestLib3.asm) INCLUDE Irvine32.inc OUTER_LOOP_COUNT=3 .data startTime DWORD ? msg1 BYTE "Please wait...",0dh,0ah,0 msg2 BYTE "Elapsed milliseconds:",0 .code main PROC mov edx,OFFSET msg1 call WriteString call GetMSeconds mov startTime,eax mov ecx,OUTER_LOOP_COUNT L1: call innerLoop loop L1 call GetMSeconds sub eax,startTime mov edx,OFFSET msg2 call WriteString call WriteDec call Crlf exit main ENDP innerLoop PROC push ecx mov ecx,0FFFFFFFFh L1: mov eax,eax loop L1 pop ecx ret innerLoop ENDP END main
堆栈操作
运行时栈(running stack):由CPU直接管理的内存数组,它使用两个寄存器:SS和ESP。SS:存放段选择器,用户模式程序不应对其修改。ESP:堆栈指针寄存器存放指向堆栈内特定位置的一个32位偏移值;通常由CALL、RET、PUSH和POP等指令间接修改。ESP指向最后压入(或添加)到堆栈上的数据。
局部可以JMP全局的 反之不行
***在保存和恢复寄存器时候,在过程 使用寄存器做返回值时候内部能将返回值的寄存器压栈或弹出
ArraySum PROC USES esi ecx 相当于PUSH ESI ,PUSH ECX,在过程结束POP ECX,POP ESI
TITLE Integer Summation Program (Sum2.asm) INCLUDE Irvine32.inc IntegerCount = 3 ; array size .data prompt1 BYTE "Enter a signed integer: ",0 prompt2 BYTE "The sum of the integers is: ",0 array DWORD IntegerCount DUP(?) .code main PROC call Clrscr mov esi, OFFSET array mov ecx, IntegerCount call PromptForIntegers call ArraySum call DisplaySum exit main ENDP PromptForIntegers PROC pushad ; save all registers mov edx, OFFSET prompt1 ; address of the prompt L1: call WriteString ; display string call ReadInt ; read integer into EAX call Crlf ; go to next output line mov [esi], eax ; store in array add esi, 4 ; next integer loop L1 popad ; restore all registers ret PromptForIntegers ENDP ArraySum PROC push esi ; save ESI, ECX push ecx mov eax,0 ; set the sum to zero L1: add eax, [esi] ; add each integer to sum add esi, 4 ; point to next integer loop L1 ; repeat for array size pop ecx ; restore ECX, ESI pop esi ret ; sum is in EAX ArraySum ENDP DisplaySum PROC push edx mov edx, OFFSET prompt2 ; display message call WriteString call WriteInt ; display EAX call Crlf pop edx ret DisplaySum ENDP END main
哦
l