把一位16进制数转化为对应的ASCII码。

把一位16进制数转化为对应的ASCII码。,第1张

补充:之前第一段话说的有问题,所以修改了下,如下:(另外提交的时候没注意,第一个兄弟的回答已经是正确的了^_^)
主要思想是0~9转为对应的ASCII码时加30h,而a,b,c,d,e,f则加37h,比30h多出来的7h就是通过adc(多加了CF的01h)以及daa(多加了06h)实现的。
先说对0~9的,以5为例,
and al,0fh
add al,90h
变为95h
daa
这个时候的daa,由于95h低位,高位都小于9,且无进位,所以不变
adc al,40h
95h + 40h + CF = D5h
daa
低位不变,高位大于9,所以加60h,变为35h,且CF = 1
最终结果为35h,即字符5对应的ascii码53
然后是A~F,以C为例:
and al,0fh
add al,90h
变为9Ch
daa
这个时候的daa,先看低位,由于低位是C,大于9,所以加06h,结果变为A2h,再看高位,高位A,大于9,所以加60h,变为02h,CF = 1(有进位)
adc al,40h
adc *** 作,02h + 40h + CF = 43h
daa
此时43h低高位都小于9,所以无变化。最后结果43h,也即C的ASCII码67

       CODES  SEGMENT
              ASSUME    CS:CODES
      START:
              PUSH      CS
              POP       DS
    ;此处输入代码段代码
              MOV       BX, 8421H   ;给定一个4位的16进制数
              MOV       AH, 2       ;向标准输出设备输出一个字符
              MOV       CX, 16      ;循环16次
      AGAIN:
              MOV       DL, '0'     ;  假定当前bx的最高位为0
              ADD       BX, BX      ;  bx=bx2 也就是左移1位
              JNC       DISP        ;  进位标志不置位时(即bx的最高位为0时)转disp
              INC       DL          ;  进位标志置位时(即bx的最高位为1时)加1
                                    ;  也就是变为 '1'  
       DISP:
              INT       21H
              LOOP      AGAIN
    
              MOV       AH, 4CH     ;程序结束
              INT       21H
       CODES  ENDS
              END       START

举个例子,6CH,转换成ASCII码,是以十六进制形式显示:6CH,还是以十进制形式显示:108?
; 本程序通过编译,运行正确
Code Segment
Assume CS:Code,DS:Code
; -----------------------------------------
; 功能:显示指定地址(Str_Addr)的字符串
; 入口:
; Str_Addr=字符串地址(要求在数据段)
; 用法: Output Str_Addr
; 用法举例:Output PromptStr
Output MACRO Str_Addr
lea dx,Str_Addr
mov ah,9
int 21h
EndM
; -----------------------------------------
; 功能:把AL中的二进制无符号数转换成显式的十进制ASCII
; 入口:AL=二进制数;di=转换后的ASCII保存地址
; 出口:无
HEXASC_Dec Proc Near
push si
push cx
push bx
push di
mov bl,10
xor cx,cx
lea di,@@Temp_Save[3]
cld
@@Divide: xor ah,ah
div bl
or ah,30h
mov [di],ah
dec di
inc cx
test al,0ffh
jnz @@Divide
push di
pop si
inc si
pop di
pop bx
rep movsb
pop cx
pop si
ret
@@Temp_Save db 4 dup()
HEXASC_Dec EndP
; -----------------------------------------
; 功能:将AL中的低4位二进制数转换成十六进制显示的ASCII码
; 入口:AL
; 出口:AL=转换后的ASCII码
AL_ASCII Proc Near
cmp al,10 ;AL<10
jb @@To_ASCII ;AL<10,按数字处理
add al,7 ;AL>=10,按大写字母处理
@@To_ASCII: add al,'0' ;转换成相应的数字或大写字母
ret
AL_ASCII EndP
; -----------------------------------------
; 功能:将AL中的字节数转换成十六进制显示的ASCII码
; 入口:AL
; 出口:AX=转换后的ASCII码
HEXASC_Hex Proc Near
push cx
mov cx,4
xor ah,ah ;将AH置0
shl ax,cl ;将AX左移4位
shr al,cl ;将AL右移4位
xchg ah,al
call AL_ASCII ;调用子程序,将AL中的值转换成相应的ASCII码
xchg ah,al
call AL_ASCII
xchg ah,al
pop cx
ret
HEXASC_Hex EndP
; -----------------------------------------
Translate db '0' ;转换方式(默认:十进制数显示;若要十六进制显示,则改为:1)
BUF db 23,35,46,57,68,79,81,98,119,243
Elements EQU ($-BUF)/Type BUF ;元素个数
Start: push cs
pop ds
push cs
pop es ;使数据段、附加段与代码段同段
cld
lea si,BUF
lea di,Temp_STr
mov cx,Elements
HEX_ASCII: lodsb
IF Translate == '0'
call HEXASC_Dec
ELSE
call HEXASC_Hex
stosw
mov al,'H'
stosb
ENDIF
mov al,','
stosb
loop HEX_ASCII
dec di
mov al,'$'
stosb
Output Temp_STr
Exit_Proc: mov ah,4ch ;结束程序
int 21h
Temp_STr:
Code ENDS
END Start ;编译到此结束
; -----------------------------------------
ADD AL,90H
DAA
ADD AL,40H
DAA
十进制数加调整指令DAA(Decimal Adjust After Addition)
该指令是用于调整AL的值,该值是由指令ADD或ADC运算二个压缩型BCD码所得到的结果。压缩型BCD码是一个字节存放二个BCD码,低四位和高四位都是一个BCD码。
其调整规则如下:
如果AL的低四位大于9,或标志位AF=1,那么,AL=AL+6,并置AF=1;
如果AL的高四位大于9,或CF=1,那么,AL=AL+60H,并置CF=1;
、如果以上两点都不成立,则,清除标志位AF和CF。
经过调整后,AL的值仍是压缩型BCD码,即:二个压缩型BCD码相加,并进行调整后,得到的结果还是压缩型BCD码。

#include <stdioh>
char hextoascii(char hex_byte)
{
    char result;
    if((hex_byte>=0)&&(hex_byte<=9))            //变成ascii数字
        result = hex_byte + 0x30;
    else if((hex_byte >= 10)&&(hex_byte <= 15)) //变成ascii大写字母
        result = hex_byte + 0x37;
    else
        result = 0xff;
    return result;
}
main()
{
    short hex_data;
    char ascii_data[10],i;
    printf("Input hex data:\n");
    scanf("%x",hex_data);
    while(hex_data)
    {
        ascii_data[i++] = hextoascii((char)(hex_data%16));
        hex_data /= 16;
    }
    printf("Output ascii data:\n");
    for(unsigned char j = 0;j < i;j++)
        printf("%c",ascii_data[j]);
}

不知你要的是C语言的还是汇编的,都给你吧
C语言的:
#include <REG51H>
typedef unsigned char uchar;
#define NUMBER 10
uchar BufferIn[NUMBER]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,0x1a,0x1b};//16进制数存放区
uchar BufferOut[2NUMBER]; //ASCII码存放区
////////////////////////////////////////////////////////////////
//功能: 将多字节16进制数转换为ASCII字符
//入口: x:待转换16进制数,x>=0且x<=F
//出口: 返回转换完成后的ASCII码字符数据,返回0为失败
////////////////////////////////////////////////////////////////
uchar GetASCII(uchar x)
{
if(x>0x0f)
{
return 0;
}

if(x>9)
{
return ('A'+x-10);
}
return ('0'+x);
}
////////////////////////////////////////////////////////////////
//主程序
////////////////////////////////////////////////////////////////
void main()
{
uchar i;

for(i=0;i<NUMBER;i++)
{
BufferOut[i2] = GetASCII(BufferIn[i]/0x10);
BufferOut[i2+1] = GetASCII(BufferIn[i]%0x10);
}
while(1);
}
汇编的:
;说明: LOOP1循环为预设10个16进制数内容的初始化程序,作为示例
ORG 0000H
LJMP START
ORG 0100H
START: MOV R2, #10 ;预置10个16进制数
MOV R0, #20H ;16进制数存放起始地址
MOV A, #12H
LOOP1: MOV @R0, A
ADD A, #13H
INC R0
DJNZ R2,LOOP1 ;循环10次送10个数
;以上至START为初始化内存,预送10个字节的数据

MOV R0, #20H ;16进制数存放起始地址
MOV R1, #30H ;ASCII数存放起始地址
MOV R2, #10 ;转换10个字节
LCALL HEXTOASC ;调用转换子程序
JMP $
;=======================================================
;HEXTOASC:将多字节16进制数转换为ASCII字符子程序
;入口: (R0)=16进制数存放起始地址指针
; (R2)=字节数
;出口: (R1)=转换完成后的ASC字符存放起始地址指针
;算法说明:0~9:(ASCII码为30H~39H)+90H后调整后无变化,结果
; 为9xH,再加40H为0DxH,调整 *** 作+60H后正好为3xH;
; A~F:(ASCII为41H~46H),+90H后为9xH,调整 *** 作+06H后
; 为01H~06H,再加40H调整后不变,正好为41H~46H;
;=======================================================
HEXTOASC:
MOV A, @R0
SWAP A
ANL A, #0FH ;处理高4位
ADD A, #90H
DA A
ADDC A, #40H
DA A
MOV @R1, A ;保存高4位
INC R1
MOV A, @R0
ANL A, #0FH ;处理低4位
ADD A, #90H
DA A
ADDC A, #40H
DA A
MOV @R1, A ;保存低4位
INC R1 ;下一个16进制数
INC R0
DJNZ R2, HEXTOASC
RET

END


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/yw/13161516.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-06-14
下一篇 2023-06-14

发表评论

登录后才能评论

评论列表(0条)

保存