于渊先生的《orange’s 一个操作系统实现》的字符串输出函数disp_str有bug会导致异常
发现在同一个函数中两次使用disp_str就会导致异常,这个问题困扰了我很久,一般来说都是堆栈的没有恢复好的问题,在反复的检查后发现堆栈并没有什么问题,disp_str是一个汇编程序,莫名觉得是符号问题,鬼使神差的使用c程序对其包装发现没有这样的问题,一直往堆栈方向想,但后来想到自己大一写汇编函数的时候都会小心翼翼的把每个涉及到的寄存器进行保护,想到这里,可能有一些使用到的寄存器没有保护到,导致出现bug了,于是乎将该函数涉及到的寄存器都做了一遍保存,在函数返回的时候进行恢复,总算是解决了。
写汇编函数的时候一定要注意对会使用到的寄存器的恢复,很难清楚调用函数的c被编译后有没有使用到这些寄存器。
disp_str:
push ebp
push esi
push edi
push eax
push ebx
mov ebp, esp
mov esi, [ebp + 24]
mov edi, [disp_pos]
mov ah, 0Fh
.1:
lodsb
test al, al
jz .2
cmp al, 0Ah
jnz .3
push eax
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop eax
jmp .1
.3:
mov [gs:edi], ax
add edi, 2
jmp .1
.2:
mov [disp_pos], edi
pop ebx
pop eax
pop edi
pop esi
pop ebp
ret 4
在经过更改之后,基本上没问题了,但是为了不浪费调用栈,在ret后还加了一个4,因为一开始调用这个函数的时候会把一个4字节的字符串指针压栈,但是加了这个4之后就出了问题了,所以4是不能加的,可能是nasm自动优化了,用别的方式把栈推掉了?而我这么做多余导致出错?总之最后的打印函数如下
disp_str:
push ebp
push esi
push edi
push eax
push ebx
mov ebp, esp
mov esi, [ebp + 24]
mov edi, [disp_pos]
mov ah, 0Fh
.1:
lodsb
test al, al
jz .2
cmp al, 0Ah
jnz .3
push eax
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop eax
jmp .1
.3:
mov [gs:edi], ax
add edi, 2
jmp .1
.2:
mov [disp_pos], edi
pop ebx
pop eax
pop edi
pop esi
pop ebp
ret
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)