push dword [esi] ; //push [ds:0x7a],为0x00000000,注意这是指第一次压入堆栈的情况
call DispInt //call指令会自动调用堆栈,esp会减4
-------------------------------------------------------------------------------------
;; 显示一个整形数
DispInt:
mov eax, [esp + 4] //注意这里esp+4是因为调入之前的call指令,因为call指令会自动把一些参数入栈,esp要减4,esp+4正好指向了第一次push进去的
0x00000000
shr eax, 24 //右移24位,这时eax的低8位存放的原来数据的高8位(31-24)
call DispAL
mov eax, [esp + 4] //注意esp这是并没有改变值,所以esp+4还是指向的0x00000000
shr eax, 16 //数据右移16位,这时eax的低8位存放的原来数据的(23-16)
call DispAL
mov eax, [esp + 4]
shr eax, 8 //这时eax的低8位存放的原来数据的(15-8)
call DispAL
mov eax, [esp + 4] //这时eax的低8位存放的原来数据的(7-0)
call DispAL
mov ah, 07h ; 0000b: 黑底 0111b: 灰字 //打印“H”
mov al, 'h'
push edi //先把edi保存起来
mov edi, [dwDispPos] //把位置数据传给edi
mov [gs:edi], ax
add edi, 4 //本来ax应该是edi+2,但是为了再空一格,所以又加了2 ,一共加4,从而得到新的位置
mov [dwDispPos], edi //把新位置传给dwDispPos的内存处
pop edi
ret
;; DispInt 结束
----------------------------------------------------------------------------------------------
;; 显示 AL 中的数字
DispAL: //主要就是一个2进制到16进制转换的过程
push ecx
push edx
push edi
mov edi, [dwDispPos]
mov ah, 0Fh ; 0000b: 黑底 1111b: 白字 //这时eax的低8位al中存放的原来数据的高8位(31-24),所以可以给ah赋值
mov dl, al //al 赋给dl,先把al的值保存起来
shr al, 4 //al右移4位,原来al中的高四位成为低四位
mov ecx, 2
.begin:
and al, 01111b //保留al的低四位,实际上是原来al的高4位,高4位变为0,这时处理的是原来al的高4位
cmp al, 9 //前者大于后者跳转 ,即al大于9跳转,al小于9不跳转。
ja .1
add al, '0' //al小于9还时用数字表示
jmp .2 //显示出来
.1:
sub al, 0Ah //al大于9就要转换为16进制,用字母的方式表示
add al, 'A'
.2:
mov [gs:edi], ax //al中要显示的数值已经转化为16进制了,就显示出来
add edi, 2
mov al, dl //这时al中低四位就是存放的原来al中的低四位,哇,设计好巧妙。
loop .begin //跳转到begin继续执行,这时就是跳转上去处理原来al中的低四位
;add edi, 2
mov [dwDispPos], edi //两次循环执行完了,把显示地址保存到dwDispPos出
pop edi
pop edx
pop ecx
ret
;; DispAL 结束