- 26
- 4月
今天很高兴成功写出了生平第一个汇编程序,程序很简单:从键盘读入一个数字,判断正负,正数输出1,负数输出-1,0时输出0。
因为汇编不是高级语言,所有的分枝都得靠跳转指令。于是老老实实地用流程图画了一下,别看就这么点功能,但输入的数字得一个一个地接收、判断(想起有穷状 态自动机来了,不知道这能不能算它的一种实现)。输出的时候也要根据正负、是否为0判断。最终这么一个小程序居然用了6处判断跳转!用C写2个if就可以 搞定的东东嘛……呵呵。
按照《代码大全(Code Complete)》上建议的方法,先把程序思路用注释全部写到源文件中去,然后一条条展开成代码,最终经过调试得到了以下可以成功运行的代码:
CODE SEGMENT ASSUME CS:CODE START: ;init XOR AX ,AX MOV BX ,0030H ;bh-negative flag, bl non-zero flag XOR CX ,CX ;input flag INPUT: ;input a charactor MOV AH,01 INT 21H CMP AL,1BH JE RETURN ;press ESC to exit CMP AL,0DH JE OUTPUT ;if it's x0d, jump to OUTPUT TEST CL,01H JNE COMMON ;if it's not the first charactor, jump to COMMON MOV CL,01H ;set input flag CMP AL,'-' JNZ COMMON ;if it's not '-', jump to COMMON MOV BH,01H ;set negative flag JMP INPUT ;jump to INPUT COMMON: CMP AL,'0' JE INPUT ;if it's '0', jump to INPUT MOV BL,31H ;set non-zero flag JMP INPUT ;jump to INPUT OUTPUT: MOV AH,02H MOV DL,0AH INT 21H ;start a new line CMP BL,'0' JE NZ ;if it's 0, '-' is of no use CMP BH,01H JNE NZ ;if negative flag is false, jump to NZ MOV DL,'-' INT 21H ;print '-' NZ: MOV DL,BL INT 21H ;print the non-zero flag MOV DL,0AH INT 21H MOV DL,0DH INT 21H ;move cursor to a new line JMP START ;get the next number RETURN: RET CODE ENDS END START
PS:期间犯了两个错误,记录一下
1.忘记了 ASSUME CS:CODE 这一句,没了代码段,造成了所有的跳转语句都报:“ Near jump or call to different CS”错误。没指定自己的代码段在哪里,一跳可不是to different CS嘛!
2.代码最后没有加RET,一接收完输入就报莫名其妙的错误。汇编毕竟是汇编,最后的CODE ENDS和END START只是给编译器看的。程序执行完毕,返回操作系统的指令也得写明。
搞定之后小研究了一个EXE文件的结构,找到一篇不错的文章: com和exe文件结构