- 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文件结构