二.Ascii码
我发现实际上很多人无法理解Ascii 十六进制 二进制 ……这些乱其八糟的东西,在这里我觉得有必要讲述一下。
ASCII 全称是 American Standard Code for Information Interchange美国信息交换标准码。起始于50年代后期,在1967年定案。ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。一般情况下我们使用的是8位的。一个字节也是8位的,因此正好能够将它们按照数字对字符一一对应起来。
比如: mov al,25h (注意,是十六进制的25h) 然后将 al 直接输出,结果就是“%”。这就是简单的对应。额外的:
十六进制 显示出来的字符
30h 0
31h 1
32h 2
33h 3
34h 4
35h 5
36h 6
37h 7
38h 8
39h 9
就是说 mov al,31h 显示出来就是 “1”。如果还不明白,不妨动手实验下面的程序:(注意:.data 不是 .data? 字符串放在后者显示不出来)
.386
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc
includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
include macro.asm
.data
buffer db 31h,32h,33h,34h,35h,36h,37h,38h,0
.CODE
START:
invoke StdOut,addr buffer
invoke ExitProcess,0
end START
需要注意的是不是所有的Ascii都是可见的,因此我们直接用记事本打开一个可执行文件时会看到很多乱码,比如我们使用记事本打开 D:\MASMPlus\Bin\CVTRES.exe 结果如下:
而使用十六进制编辑软件ultraEdit打开这个文件,看到的就是:
左边是按照十六进制表示的,右边是左边数值对应的Ascii,很多无法显示的Ascii都用“.”来表示了。可以看出来和用Notepad打开的看起来很“像”。
观察上面那个十六进制对Ascii的表可以发现一点点“规律”,一个数字 N 加上30h之后显示出来就是这个数字。如果我们要按照十六进制显示 AL中的数值,就可以将Al的高4位加上30h显示一下,再按照同样的方式处理低4位。不过 0-9的数值和A-F的并不连续,这里需要特殊处理一下。下面的dos程序段就是这个原理(非常不幸的是Dos Box中,我们的conole程序无法直接调用int 21h).
;Input AL,Bl,No Output
ShowAL proc
pusha
mov dl,al ;保存AL
mov cl,04
shr al,cl ;AL高4位移至低4位
mov cx,02h ;循环2次
Low4bit: cmp al,09
jbe larger ;低4位超过9
add al,07
larger: add al,30h
push cx
mov bh,0h
mov cx,1h
mov ah,09h
int 10h
pop cx
add shX,1
call SetCur
mov al,dl ;恢复保存
and al,0Fh
loop Low4bit
popa
ret
ShowAL endp
如果有兴趣的话,可以将这个程序改造为你自己的console的showal.
我发现实际上很多人无法理解Ascii 十六进制 二进制 ……这些乱其八糟的东西,在这里我觉得有必要讲述一下。
ASCII 全称是 American Standard Code for Information Interchange美国信息交换标准码。起始于50年代后期,在1967年定案。ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。一般情况下我们使用的是8位的。一个字节也是8位的,因此正好能够将它们按照数字对字符一一对应起来。
比如: mov al,25h (注意,是十六进制的25h) 然后将 al 直接输出,结果就是“%”。这就是简单的对应。额外的:
十六进制 显示出来的字符
30h 0
31h 1
32h 2
33h 3
34h 4
35h 5
36h 6
37h 7
38h 8
39h 9
就是说 mov al,31h 显示出来就是 “1”。如果还不明白,不妨动手实验下面的程序:(注意:.data 不是 .data? 字符串放在后者显示不出来)
.386
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc
includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
include macro.asm
.data
buffer db 31h,32h,33h,34h,35h,36h,37h,38h,0
.CODE
START:
invoke StdOut,addr buffer
invoke ExitProcess,0
end START
需要注意的是不是所有的Ascii都是可见的,因此我们直接用记事本打开一个可执行文件时会看到很多乱码,比如我们使用记事本打开 D:\MASMPlus\Bin\CVTRES.exe 结果如下:
而使用十六进制编辑软件ultraEdit打开这个文件,看到的就是:
左边是按照十六进制表示的,右边是左边数值对应的Ascii,很多无法显示的Ascii都用“.”来表示了。可以看出来和用Notepad打开的看起来很“像”。
观察上面那个十六进制对Ascii的表可以发现一点点“规律”,一个数字 N 加上30h之后显示出来就是这个数字。如果我们要按照十六进制显示 AL中的数值,就可以将Al的高4位加上30h显示一下,再按照同样的方式处理低4位。不过 0-9的数值和A-F的并不连续,这里需要特殊处理一下。下面的dos程序段就是这个原理(非常不幸的是Dos Box中,我们的conole程序无法直接调用int 21h).
;Input AL,Bl,No Output
ShowAL proc
pusha
mov dl,al ;保存AL
mov cl,04
shr al,cl ;AL高4位移至低4位
mov cx,02h ;循环2次
Low4bit: cmp al,09
jbe larger ;低4位超过9
add al,07
larger: add al,30h
push cx
mov bh,0h
mov cx,1h
mov ah,09h
int 10h
pop cx
add shX,1
call SetCur
mov al,dl ;恢复保存
and al,0Fh
loop Low4bit
popa
ret
ShowAL endp
如果有兴趣的话,可以将这个程序改造为你自己的console的showal.