![]() |
#2
Alar302011-11-27 09:54
|

[原创]进制数据输出的通用程序
*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: liyun2060 E-mail:blakcuttlefish@*/ 时间: 2007-9-5 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------
昨天看了别人的文章,然后写了一个进制输出的程序,程序实在是太乱了。并且可调试性也很差。于是今天重新写了一个。
进制输出的原理很简单,就是先建一个‘0123456789ACDEF’的数据表
然后根据 除(2,10或者16 这要看你想以什么进制数据形式输出了) 取余,再拿商去除(2,10,16) 再取余的原理。 拿余数跟数据表比较,取得相应的ASCII码。
哎说不清楚,还是看程序吧。自认为程序写的还算清晰明了
;Revision Declare Modified by zaixuexi
;*/ --------------------------------------------------------------------------------------
;*/ source:https://www.bc-cn.net
;*/ author:zaixuexi
;*/ date: 2011-11-26
;*/ email: asmedu@
;*/ revision declare:
;*/ 1.add self-estimated c source code
;*/ 2.adjust all asm source code lower-case style.
;*/ 3.keep all original code designment
;*/ --------------------------------------------------------------------------------------
;typedef unsigned char uint8_t;
;typedef unsigned short uint16_t;
;global variable declaration
uint16_t *g_table_t2;
assume cs:codes
codes segment
start:
mov ax,cs
mov ds,ax ;code : { *(.text) *(.data) }; (ld scripts syntax)
mov ax,0b800h
mov es,ax ;uint16_t *vga_base = (uint16_t *)0xb800;
mov cl,2 ;uint8_t radix = 2;
mov dl,011111111b ;uint8_t value = 0xff;
call data_turn
mov cx,ax ;uint16_t count = data_turn(ch, i);
;original author used ABI: use register pass parameter, return value in ax.
mov di,160*10+40 ;uint16_t pos = 160*10+40;
moves:
mov ah,[si]
mov es:[di],ah
inc si ;vga_base[pos] = *g_table_t2++;
add di,2 ;pos += 2;
loop moves ;while (count--);
mov ah,04ch
int 21h ;exit(0);
;/**////////////////////////////////////////////////////////////////////////////////转换程序开始nc
;数制转换通用程序
;功能:将内存中的数据转换成以2进制 16进制 或 10进制 表示的 相应的ASCII码字符串
;进口参数CL 需要转换成的进制
;进口参数DL 被转换数
;出口参数AX 转换后的字符串的长度
;出口参数SI 转换后的字符串的起始偏移地址 段地址为CS
data_turn proc ;uint16_t data_turn(uint8_t value, uint8_t radix);
jmp turn_start ;goto turn_start;
table_t1 db '0123456789abcdef' ;const uint8_t *table_t1 = "0123456789abcdef";
table_t2 db 8 dup(?) ;用来存储转换后的数据 ;uint8_t table_t2[8];
turn_start:
push ds
push bx ;uint8_t index;
mov ax,cs
mov ds,ax
mov si,7 ;uint 16_t offset = 7;
mov al,dl ;uint16_t value = (uint16_t)value;
cmp al,0 ;if (ch == 0) goto dl_zero;
je dl_zero ;如果被转换数为0 则直接将0写入table_t2+7处
lp:
xor bh,bh
xor ah,ah
div cl
mov bl,ah ;index = value % radix; value /= radix;
mov bh,table_t1[bx]
mov table_t2[si],bh
dec si ;table_t2[offset--] = table_t1[index];
cmp al,0
je turn_end ;if (value == 0) goto turn_end;
jmp lp ;goto lp;
dl_zero:
mov ds:[table_t2+7],'0' ;table_t2[offset] = 0x30;
mov ax,1 ;uint16_t return_val = 1;
lea si,table_t2
add si,7 ;g_table_t2 = table_t2 + 7;
jmp over ;goto over;
turn_end:
mov ax,7
sub ax,si ;index = 7 - offset;
lea si,table_t2
add si,8
sub si,ax ;g_table_t2 = table_t2 + 8 - index;
over:
pop bx
pop ds
ret ;return return_val;
data_turn endp
;/**//////////////////////////////////////////////转换程序结束
codes ends
end start
简单评论: 代码结构不是很好,算法思路清晰.*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: liyun2060 E-mail:blakcuttlefish@*/ 时间: 2007-9-5 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------
昨天看了别人的文章,然后写了一个进制输出的程序,程序实在是太乱了。并且可调试性也很差。于是今天重新写了一个。
进制输出的原理很简单,就是先建一个‘0123456789ACDEF’的数据表
然后根据 除(2,10或者16 这要看你想以什么进制数据形式输出了) 取余,再拿商去除(2,10,16) 再取余的原理。 拿余数跟数据表比较,取得相应的ASCII码。
哎说不清楚,还是看程序吧。自认为程序写的还算清晰明了
;Revision Declare Modified by zaixuexi
;*/ --------------------------------------------------------------------------------------
;*/ source:https://www.bc-cn.net
;*/ author:zaixuexi
;*/ date: 2011-11-26
;*/ email: asmedu@
;*/ revision declare:
;*/ 1.add self-estimated c source code
;*/ 2.adjust all asm source code lower-case style.
;*/ 3.keep all original code designment
;*/ --------------------------------------------------------------------------------------
;typedef unsigned char uint8_t;
;typedef unsigned short uint16_t;
;global variable declaration
uint16_t *g_table_t2;
assume cs:codes
codes segment
start:
mov ax,cs
mov ds,ax ;code : { *(.text) *(.data) }; (ld scripts syntax)
mov ax,0b800h
mov es,ax ;uint16_t *vga_base = (uint16_t *)0xb800;
mov cl,2 ;uint8_t radix = 2;
mov dl,011111111b ;uint8_t value = 0xff;
call data_turn
mov cx,ax ;uint16_t count = data_turn(ch, i);
;original author used ABI: use register pass parameter, return value in ax.
mov di,160*10+40 ;uint16_t pos = 160*10+40;
moves:
mov ah,[si]
mov es:[di],ah
inc si ;vga_base[pos] = *g_table_t2++;
add di,2 ;pos += 2;
loop moves ;while (count--);
mov ah,04ch
int 21h ;exit(0);
;/**////////////////////////////////////////////////////////////////////////////////转换程序开始nc
;数制转换通用程序
;功能:将内存中的数据转换成以2进制 16进制 或 10进制 表示的 相应的ASCII码字符串
;进口参数CL 需要转换成的进制
;进口参数DL 被转换数
;出口参数AX 转换后的字符串的长度
;出口参数SI 转换后的字符串的起始偏移地址 段地址为CS
data_turn proc ;uint16_t data_turn(uint8_t value, uint8_t radix);
jmp turn_start ;goto turn_start;
table_t1 db '0123456789abcdef' ;const uint8_t *table_t1 = "0123456789abcdef";
table_t2 db 8 dup(?) ;用来存储转换后的数据 ;uint8_t table_t2[8];
turn_start:
push ds
push bx ;uint8_t index;
mov ax,cs
mov ds,ax
mov si,7 ;uint 16_t offset = 7;
mov al,dl ;uint16_t value = (uint16_t)value;
cmp al,0 ;if (ch == 0) goto dl_zero;
je dl_zero ;如果被转换数为0 则直接将0写入table_t2+7处
lp:
xor bh,bh
xor ah,ah
div cl
mov bl,ah ;index = value % radix; value /= radix;
mov bh,table_t1[bx]
mov table_t2[si],bh
dec si ;table_t2[offset--] = table_t1[index];
cmp al,0
je turn_end ;if (value == 0) goto turn_end;
jmp lp ;goto lp;
dl_zero:
mov ds:[table_t2+7],'0' ;table_t2[offset] = 0x30;
mov ax,1 ;uint16_t return_val = 1;
lea si,table_t2
add si,7 ;g_table_t2 = table_t2 + 7;
jmp over ;goto over;
turn_end:
mov ax,7
sub ax,si ;index = 7 - offset;
lea si,table_t2
add si,8
sub si,ax ;g_table_t2 = table_t2 + 8 - index;
over:
pop bx
pop ds
ret ;return return_val;
data_turn endp
;/**//////////////////////////////////////////////转换程序结束
codes ends
end start
