x86汇编-栈-18

117 阅读2分钟

  • 先进后出的数据结构
  • 入栈
    push ax 将ax寄存器放到栈中
  • 出栈
    pop ax 将栈顶元素放到ax寄存器中
  • 栈相关的寄存器
    ss: 栈段寄存器 栈段地址
    sp: 栈偏移指针
    栈的物理地址: ss<<4 + sp
  • 注意点
    8086中push/pop的操作必须是16位

使用栈完成1+2+3+...+100

	jmp start

message db '1+2+3+...+100='

start:
	mov ax, 0x07c0
	mov ds, ax		; 设置数据段起始地址
	mov ax, 0xb800
	mov es, ax		; 附加数据段 显存起始位置
	mov si, message	; message偏移地址
	mov ax, cs
	mov ss, ax		; 设置栈段起始地址
	mov sp, 0		; 设置栈段偏移指针
	mov di, 0		; 显存偏移地址
	mov cx, start-message	; 循环次数
	
	
  printmessage:		; 将1+2+3+...+100=打印到屏幕上
	mov al, [si]	; 第一次循环 字符1
	mov [es:di], al	; 字符输出到屏幕上
	inc di			; 指向显存下一个位置
	mov byte [es:di], 0x07	; 设置字符模式
	inc di			; 指向显存下一个位置
	inc si			; 指向源字符串的下一个位置
	loop printmessage	; 循环

	xor ax, ax		; ax寄存器清空 作为结果使用
	mov cx, 1		; cx从1100 递增
  sum:				; 计算1+2+3+...+100的结果
	add ax, cx		; 累加操作 结果存回ax
	inc cx			; cx递增
	cmp cx, 100		; 判断cx是否到了100
	jle sum			; if(cx < 100) goto sum;



	xor cx, cx		; cx记录数位长度 ax有几个数位
	mov bx, 10		; 除数 10
  breakdown:		; 对ax按数位分解
	xor dx, dx		; div指令 dx是被除数高16位 ax是被除数低16位
	inc cx			; 数位递增
	div bx			; 余数在dx 商在ax
	push dx			; 把dx放到栈区
	cmp ax, 0		; ax是否等于0 即每一次除法的商
	jne breakdown	; if(ax != 0) goto breakdown;

  printresult:		; 输出1+2+3+...+100的结果 5050
	pop dx			; 栈顶元素弹出
	add dl, 0x30	; 数字转字符
	mov [es:di], dl
	inc di
	mov byte [es:di], 0x07
	inc di
	loop printresult

; 主引导扇区格式
jmp $
times 510-($-$$) db 0
db 0x55, 0xaa
	

结果

捕获.PNG