汇编语言学习笔记-三个尝试

    科技2025-11-11  13

    使用工具

    常用的汇编语言工具:提供下载链接程序入口

    尝试一

    要求:实现两数的求和

    ;Program: 两个数的相加 ;Author: 龙文汉 ;Date: 20.10.7 .386 .MODEL FLAT ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD INCLUDE io.h cr EQU 0dh Lf EQU 0ah .STACK 4096 .DATA number1 DWORD ? number2 DWORD ? prompt1 BYTE "Enter first number: ",0 prompt2 BYTE "Enter second number: ",0 string BYTE 40 DUP (?) label1 BYTE cr,Lf,"The sum is" sum BYTE 11 DUP (?) BYTE cr,Lf,0 .CODE _start: output prompt1 input string ,40 atod string mov number1,eax output prompt2 input string ,40 atod string mov number2,eax mov eax,number1 add eax,number2 dtoa sum,eax output label1 INVOKE ExitProcess,0 PUBLIC _start END

    尝试二

    要求:

    写一个完整的8086汇编语言程序,满足一下要求:

    A. 从键盘输入自己的姓名,显示输出“Hello,姓名”,其中“姓名”为自己输入的姓名。

    ;Program: 输入自己的名字 ;Author: 龙文汉 ;Date: 20.10.7 .386 .MODEL FLAT ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD INCLUDE io.h ; header file for input/output cr EQU 0dh ; carriage return character Lf EQU 0ah ; line feed .STACK 4096 ; reserve 4096-byte stack .DATA ; reserve storage for data name1 DWORD 10 DUP (?) prompt BYTE "Enter your name:" string BYTE 40 DUP (?) prompt1 BYTE "Hello," .CODE ; start of main program code _start: output prompt input name1,10 output prompt1 output name1 INVOKE ExitProcess, 0 ; exit with return code 0 PUBLIC _start ; make entry point public END ; end of source code

    尝试三

    要求:

    写一个完整的8086汇编语言程序,满足一下要求:

    A. 数据段申请一个存储数据的字长数据(一个长度为word的变量),该数据存储的值20。

    B. 数据段申请一个存储数据的双字字长数据(一个长度为dword的变量),该数据的值从键盘输入。

    C. 显示上述两个数据在屏幕上。

    ;Program: 实验1,3 ;Author: 龙文汉 ;Date: 20.10.7 .386 .MODEL FLAT ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD INCLUDE io.h ; header file for input/output cr EQU 0dh ; carriage return character Lf EQU 0ah ; line feed .STACK 4096 ; reserve 4096-byte stack .DATA ; reserve storage for data number1 WORD 20 number2 DWORD 20 DUP (?) prompt1 BYTE "ENTER THE numb2:" BYTE cr,Lf,0 string BYTE 40 DUP (?) string2 WORD 20 DUP (?) BYTE cr,Lf,0 prompt2 BYTE "第一个数" BYTE cr,Lf,0 prompt3 BYTE cr,Lf,"第二个数" BYTE cr,Lf,0 .CODE ; start of main program code _start: output prompt1 input string,40 atod string mov number2,eax itoa string2,number1 output prompt2 output string2 mov eax,number2 dtoa number2,eax output prompt3 output number2 INVOKE ExitProcess, 0 ; exit with return code 0 PUBLIC _start ; make entry point public END ; end of source code

    知识点

    cr,Lf的使用 cr EQU 0dh ; carriage return character(回车) Lf EQU 0ah ; line feed(换行) prompt3 BYTE cr,Lf,"第二个数" BYTE cr,Lf,0

    先给0dh(回车),0ah(换行)定义两个赋值名cr,Lf,方便操作. 而在之后的操作中,可以直接将其付给变量。特别注意:回车:将光标重新移到本行的开头,换行:将光标移动到下一行的相同位置。因此,这两个通常同时使用。

    程序整体介绍(第一个为例子) .386:指示性命令,如果没有.386,MASM就只会接受8086/8088系列的指令,有了这条指令,汇编器就可以接受80186,80286以及80386等处理器的指令。.MODEL FLAT:指示性命令,告诉汇编器用一个平面储存模式来生成32位的代码。ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD: 指示性命令,PROTO用来生成一个函数体。在本例中,函数的名字是ExitProcess,用来结束程序的系统函数。它只有一个符号位dwExitCode的双字节参数。INCLUDE io.h:指示性语句,当编译该程序时,它只是汇编器拷贝一个文件IO.H到程序中,源文件没有经过修改,仍然包括INCLUDE语句,但是为了编译,汇编器最后会将io.h插入到INCLUDE语句中cr EQU 0dh;Lf EQU 0ah:使用EQU符号赋值。在之后的代码中,该符号就表示相应的值。.STACK:告诉汇编器运行时堆栈要保留多少字节,通常是保留4096个字节。栈通常用来过程调用。.DATA:程序的数据段的开始,该数据段保留了变量的内存空间。BYTE,DWORD分别用来储存字节和双字。number1 DWORD ?:保留一个双字空间,将符号名和地址00000000关联起来(因为它是第一个数据项),(?)表示这个双字还没有被定义初始值。number2 DWORD ?:同样的,保留另一个双字空间,并且将符号名和地址00000004关联起来。程序运行时,number1和number2不仅仅是地址不同,而且这两个双字在连续的内存中。prompt1 BYTE "Enter first number: ",0:有两个操作数,字符串”Enter first number: “和数字0.它为引号内的每个字符保留一个字节长度,为数字0保留一个字节长度。对于每个字符,该字节储存字符的ASCII码值。而对于数字,则储存该数字的二进制补码。string BYTE 40 DUP (?):为字符串保留了40个未经初始化的字节,DUP运算符要求括号中项重复。label1 BYTE cr,Lf,"The sum is ":有三个操作数,保留了13个字节的空间。开始的2个字节时0D,0A,之后就是引号中的字符串。注意,对于BYTE指令或者下一条指令,这里并没有尾随0操作数,所以结尾就没有00字节。.CODE:指示性语句,开始。代码行只有一个标号。_start::标识了这个程序的入口点,即第一条执行语句的地址。程序员可选择取名,但是通常使用_start来标识开始。output prompt1:用于显示储存在prompt1的地址的字符串,使用空字符(00)字节来结束显示。在这个程序中,用户按要求输入第一个数字,由于在提示符后,没有返回值或换行符,所以光标仍然停在冒号和两个空格的后面的一行。input string, 40:函数型的宏,让机器暂停,等待用户从键盘输入字符,直到敲回车来结束输入。第一个操作数(string)定义了这些字符的ASCII码要储存的位置。第二个操作数(40)定义了输入的字符的最大长度。atod string:input宏指令输入了ASCII代码,但是CPU只能对二进制补码数做运算,因此atod宏(把ASCII码转化为双字节整型)扫描为单操作数地址的内存,然后将其中的ASCII代码转化为相应的二进制补码的双字,将结果储存在EAX中。move number1,eax:指令性语句。助记符mov代表”move“,但是该指令实际上是一个复制操作,如同高级语言中的赋值语句。这个特定的指令把eax寄存器中的数值复制到地址为number1的内存双字中add eax,number2:加法,将第二个数字加到第一个数字中,假发必须在寄存器中执行。dtoa sum,eax:使用宏dtoa(把双字整型转化为ASCII),将寄存器中的值转化为ASCII并且放入sum中。不足部分在开头用空格字符填空。output label1:显示从标号label1到空字节(00)字符的储存器的内容 。因为sum中的未定义的字节已经赋予了ASCII码值,所以,这条没有标号的BYTE指令中,内存的第一个空字节将是跟在回车符和换行符之后的一个字符。INVOKE ExitProcess 0:是一个调用过程ExitProcess的指令,在过程中,参数dwExitCode的值是0.它的功能是终止这个程序,返回0告诉操作系统这个程序已经运行结束。(非0表示其他错误情况)PUBLIC_start:公开入口点,使得这个入口点的地址在文件外也可以看见,因此当它构成一个可执行文件,链接器可以识别执行的第一条指令。END:表示程序的结束,后面不能跟任何语句。
    Processed: 0.019, SQL: 8