动态数据结构是一种常用的数据结构,在事先不知道所处理数据容量的情况,用动态数据是一种行之有效的方法,也为许多C语言程序员所采用。在汇编语言中,我们也可以采用动态数据的方式来存储数据,并进行链表的遍历。
为了使读者尽快理解本例的功能,我们把与之相似功能的C语言程序书写如下:
#include#include struct link { int data ; struct link *next ; }; void main( ) {struct link *head=NULL, *temp, *pt; int i ; for (i = 20 ; i > 0; i--) {?? ;生成20个结点的链表 temp = (struct link *)calloc(1,sizeof(struct link)) ; ;申请一个结点的空间 if (temp == NULL) break ;?;若分配内存失败 temp->data = i ; temp->next = NULL ; if (head == NULL) head = temp ; else pt->next = temp ; pt = temp ; } while (head != NULL) {?;遍历结点并输出其数据字段 printf("%d ",head->data); pt = head ;?head = head->next;?free(pt); } }
例10.13 编写一个程序用动态链表存储20,19,……,1,并用遍历链表的方法来显示每个结点的数值。
解:
.MODEL SMALL, C .DATA Head DW 0 ;链表的头指针,初值为空 PT DW ? ;临时链表指针:当前的链表尾 Buff DB ?, ?, "$" ;存放输出结果的缓冲区 CRLF DB 0DH, 0AH, "$" ;回车、换行信息 .CODE DispMsg PROC USES AX DX, Msg:PTR BYTE ;显示字符串Msg …… ;参见例10.7 DispMsg ENDP .STARTUP MOV CX, 20 .REPEAT MOV BX, 1 ;申请内存的字节数=BX×16 MOV AH, 48H INT 21H ;申请内存的空间 .BREAK .IF CARRY? ;申请内存失败 MOV ES, AX ;AX=申请内存的段地址 MOV WORD PTR ES:[0], CX ;给第一个字赋值 MOV WORD PTR ES:[2], 0 ;给第二个字置“空”(NULL) .IF Head==0 MOV Head, ES ;保存链表的头指针 .ELSE PUSH DS MOV DS, PT MOV WORD PTR DS:[2], ES ;把当前申请到的结点链到链表中 POP DS .ENDIF MOV PT, ES ;当前结点向后移 .UNTILCXZ MOV BX, Head ;从头开始遍历链表 .WHILE (BX!=0) MOV ES, BX ;第一个结点的段地址 MOV AX, ES:[0] ;取第一个结点的数据字段值 MOV DL, 10 IDIV DL ADD AX, 3030H ;把结点的值转换成字符 LEA BX, BUFF MOV [BX], 2020H ;把字符缓冲区清空 .IF AL>30H ;若十位有非零值,则存储其字符 MOV [BX], AL INC BX .ENDIF MOV [BX], AH ;存储个位字符 INVOKE DispMsg, ADDR Buff ;显示结点数据的字符串 INVOKE DispMsg, ADDR CRLF ;显示回车、换行 MOV BX, ES:[2] ;BX=下一个结点的段地址 MOV AH, 49H ;当前结点的段地址已在ES中 INT 21H ;释放当前结点所占的空间 .ENDW .EXIT 0 END