nasm : 堆栈平衡的函数调用
来源:互联网 发布:mac mini 2014 换内存 编辑:程序博客网 时间:2024/05/02 00:40
更新 disp_char_repeat, 使写入的字符和背景不同
效果图:
; /// 重复显示字符disp_char_repeat:mov bp, sppush bp;(9)、功能 09H;功能描述:在当前光标处按指定属性显示字符;入口参数:AH=09H;AL=字符;BH=显示页码;BL=属性(文本模式)或颜色(图形模式);CX=重复输出字符的次数;出口参数:无;push PAGE_0 ; ///< STACK_PARAM_4;push COLOR_BG_READ_FG_WHITE ; ///< STACK_PARAM_3;push CHAR_TO_DISP ; ///< STACK_PARAM_2;push CHAR_COUNT ; ///< STACK_PARAM_1mov ax, STACK_PARAM_4mov bh, al ; no.0 page mov ax, STACK_PARAM_3mov bl, al ; char color, 红底白字mov ax, STACK_PARAM_1mov cx, ax ; char countmov ax, STACK_PARAM_2 ; char contentmov ah, 09h ; 在当前光标处按指定属性显示字符int 10hpop bpmov sp, bpret
<bk on 2015_0919_1226>
做实验时,发现有时执行的效果不科学。
开始直接烧到U盘0扇区,很麻烦。一直找不到错在哪.
后来用bochsdbg单步,很快发现了问题.
* 参数传递时, [bp + 2]为栈中参数的开始
* 函数调用完,需要调用者进行堆栈平衡
bochs挺好用的, 调试利器. 写的很人性化,只要用过别的调试器,很快上手,命令不多,10几个. 命令字的助记符也很好记.
显示效果和裸机上相同.
; @file boot_disp_string_by_call.asm; @brief 启动后显示一些信息; @note 编译命令行 ; cd D:\prj\nasm_prj\boot\boot_dispmsg; d:; C:\nasm\nasm.exe -f bin -d UBOOT -l boot_disp_string_by_call.list boot_disp_string_by_call.asm -o boot_2015_0919_0833; @note 将boot_2015_0919_0833写U盘0扇区; @note 效果 : 显示一句话; /// 栈上的参数; /// 进入函数后,栈上保存的参数为: ; /// [sp + 0]返回地址; /// [sp + 2]参数1(左1); /// [sp + 4]参数2(左2); /// [sp + 6]参数3(左3); /// | STACK 0xffce [0x7c13]; /// | STACK 0xffd0 [0x0000]; /// | STACK 0xffd2 [0x0000]; /// | STACK 0xffd4 [0x0000]; /// 此时 sp 指向函数返回地址; /// 函数入口保存现场; /// mov bp, sp; /// push bp; /// 此时 bp 指向函数返回地址; /// 所以在函数中使用入参时, ; /// [bp + 0] 是函数返回地址; /// [bp + 2]参数1(左1); /// [bp + 4]参数2(左2); /// [bp + 8]参数3(左3) ...%define STACK_PARAM_1 [bp + 2]%define STACK_PARAM_2 [bp + 4] ; ///< 对于16位汇编, offset是2,而不是4%define STACK_PARAM_3 [bp + 6]%define STACK_PARAM_4 [bp + 8]%define STACK_PARAM_5 [bp + 10]%define STACK_PARAM_6 [bp + 12]%define STACK_PARAM_7 [bp + 14]%define STACK_PARAM_8 [bp + 16]%define STACK_PARAM_9 [bp + 18]%define PAGE_0 0 ; ///< 显存页0%define COLOR_BG_READ_FG_WHITE 47h ; ///< 红底白字%define CHAR_TO_DISP '=' ; ///< 要显示的字符内容%define CHAR_COUNT 40 ; ///< 字符个数, 通过实验, 果真能看到一行是80个字符%define CURSOR_X_0 0%define CURSOR_Y_0 0%define CURSOR_X_1 1%define CURSOR_Y_1 1%define CURSOR_X_2 2%define CURSOR_Y_2 2%define CURSOR_X_3 3%define CURSOR_Y_3 3%define CURSOR_X_4 4%define CURSOR_Y_4 4%define CURSOR_X_5 5%define CURSOR_Y_5 5org 0hmov ax, cxmov ds, axmov es, axcall clear_screen ; ///< 清屏nop; /// 将入参从右往左入栈; /// 在调试模式下,单步vs2010中编写的程序反汇编,是这样的; /// 设置光标到(0,0)push CURSOR_Y_0 ; ///< STACK_PARAM_3push CURSOR_X_0 ; ///< STACK_PARAM_2push PAGE_0 ; ///< STACK_PARAM_1call set_cursor ; ///< set_cursor(PAGE_0, CURSOR_X_1, CURSOR_Y_2)pop ax;///< 堆栈平衡pop axpop axcall print_line40; /// 设置光标到(1,1)push CURSOR_Y_1push CURSOR_X_1push PAGE_0call set_cursor ; ///< set_cursor(PAGE_0, CURSOR_X_1, CURSOR_Y_2)pop ax;///< 堆栈平衡pop axpop axcall print_line40; /// 设置光标到(2,2)push CURSOR_Y_2push CURSOR_X_2push PAGE_0call set_cursor ; ///< set_cursor(PAGE_0, CURSOR_X_1, CURSOR_Y_2)pop ax;///< 堆栈平衡pop axpop axcall print_line40; /// 设置光标到(3,3)push CURSOR_Y_3push CURSOR_X_3push PAGE_0call set_cursor ; ///< set_cursor(PAGE_0, CURSOR_X_1, CURSOR_Y_2)pop ax;///< 堆栈平衡pop axpop axcall print_line40; /// >>push CURSOR_Y_4push CURSOR_X_4push PAGE_0call set_cursor ; ///< set_cursor(PAGE_0, CURSOR_X_1, CURSOR_Y_2)pop ax;///< 堆栈平衡pop axpop axcall print_line40; /// >>jmp $ ; 死循环print_line40:mov bp, sppush bppush PAGE_0 ; ///< STACK_PARAM_1push COLOR_BG_READ_FG_WHITE ; ///< STACK_PARAM_2push CHAR_TO_DISP ; ///< STACK_PARAM_3push CHAR_COUNT ; ///< STACK_PARAM_4call disp_char_repeat ; 调用函数-显示字符串pop ax;///< 堆栈平衡pop axpop axpop axpop bpmov sp, bpret; /// 清屏clear_screen:mov bp, sppush bp;(7)、功能 06H 和 07H;功能描述:初始化屏幕或滚屏;入口参数:AH=06H——向上滚屏,07H——向下滚屏;AL=滚动行数(0——清窗口);BH=空白区域的缺省属性;(CH、CL)=窗口的左上角位置(Y 坐标,X 坐标);(DH、DL)=窗口的右下角位置(Y 坐标,X 坐标);出口参数:无mov ah, 6hmov al, 0mov bh, 17h ; ///< 蓝底白字,光标闪烁mov cl, 0mov ch, 0mov dl, 79mov dh, 24int 10hpop bpmov sp, bpret; /// 设置光标位置set_cursor:mov bp, sppush bp;push CURSOR_Y_0 ; ///< STACK_PARAM_3;push CURSOR_X_0 ; ///< STACK_PARAM_2;push PAGE_0 ; ///< STACK_PARAM_1mov ax, STACK_PARAM_1mov bh, al ; ///< display page numbermov ax, STACK_PARAM_2mov dl, al ; ///< cursor column, CURSOR_X_Nmov ax, STACK_PARAM_3mov dh, al ; ///< cursor row, CURSOR_Y_Nmov ah, 2mov al, 0int 10hpop bpmov sp, bpret; /// 重复显示字符disp_char_repeat:mov bp, sppush bp;push PAGE_0 ; ///< STACK_PARAM_4;push COLOR_BG_READ_FG_WHITE ; ///< STACK_PARAM_3;push CHAR_TO_DISP ; ///< STACK_PARAM_2;push CHAR_COUNT ; ///< STACK_PARAM_1mov ax, STACK_PARAM_4mov bh, al ; no.0 page ; /// 按照原有的属性重复写字符, 这的颜色没用了mov ax, STACK_PARAM_3mov bl, al ; char color, 红底白字mov ax, STACK_PARAM_1mov cx, ax ; char countmov ax, STACK_PARAM_2 ; char contentmov ah, 0ah ; bios 10# function = write char to UIint 10hpop bpmov sp, bpret; /// 做个标记,在拷贝到U盘的前后,都可以确认是否为自己最新的修改str_build_time db 'build on 2015_0919_1003', 0len_str_build_time equ ($-str_build_time) ; ///< 串长度times 510-($-$$) db 0 ; 用0填充剩余空间,使该段二进制代码正好为512字节dw 0aa55h ; 结束标记
0 0
- nasm : 堆栈平衡的函数调用
- 调用函数后的堆栈平衡
- 函数调用中的堆栈平衡
- 函数的调用堆栈
- 函数的调用及堆栈
- 函数调用堆栈的理解
- 函数调用的堆栈分析
- 函数的调用堆栈过程
- 如何在VC中汇编,调用Nasm编写的函数
- 如何在VC中汇编,调用Nasm编写的函数
- 如何在VC中汇编,调用Nasm编写的函数
- 堆栈平衡的说明
- 堆栈平衡的应用
- 小结:VC的函数堆栈的平衡与局部变量
- printf函数遵守C调用规范,即参数 从右至左 压栈,堆栈由调用者平衡
- c程序调用nasm汇编函数
- C函数调用与堆栈的变化
- 显示JavaScript函数调用堆栈的方法
- js ,php 等方法获取当前窗口URL
- 解决no session or session was closed的问题
- 获取状态栏高度工具类
- 布局
- Eddystone简要介绍
- nasm : 堆栈平衡的函数调用
- 一种将通讯录和即时通讯软件整合的方法及装置
- 經STMP發送電郵 - 簡單
- windows平台MingW环境下编译FFMPEG及X264
- 1588: [HNOI2002]营业额统计(Splay树入门)
- WebRTC VideoEngine超详细教程(一)——视频通话的基本流程
- debian repertory && source.list
- hdu 3038D - How Many Answers Are Wrong [kuangbin带你飞]专题五 并查集
- win32 socket编程 示例(功能简单,完善)