如何使用小代码空间减少十六进制 ASCII 字符转换的代码空间?
在嵌入式应用程序中,我的空间非常有限(注 1)。我需要将字节从串行 I/O 转换为 ASCII 值“0”到“9”和“A”到“F”到通常的十六进制值 0 到 15。此外,所有其他 240 种组合,包括“ a' 到 'f',需要被检测(作为错误)。
诸如此类的库函数scanf(), atoi(), strtol()
太大而无法使用。
速度不是问题。代码大小是限制因素。
我目前的方法将 256 个字节代码重新映射为 256 个代码,使得 '0' 到 '9' 和 'A' 到 'Z' 的值是 0 - 35。 任何关于如何减少或不同方法的想法都值得赞赏。
unsigned char ch = GetData(); // Fetch 1 byte of incoming data;
if (!(--ch & 64)) { // decrement, then if in the '0' to '9' area ...
ch = (ch + 7) & (~64); // move 0-9 next to A-Z codes
}
ch -= 54; // -= 'A' - 10 - 1
if (ch > 15) {
; // handle error
}
注 1: 用于引导加载程序的 PIC 保护存储器中有 256 条指令用于代码和常量数据(1 字节数据需要 1 条指令)。此代码需要大约 10 条指令。当前的 ap 需要重写 & 只需要 1 条备用指令,即使减少 1 条指令也是有价值的。我一点一点地经历它。也看过整体重建。
注:PIC16。我更喜欢用“C”编写代码,但必须尽其所能。汇编代码如下。不需要快速回答。
if (!(--ch & 64)) {
002D:DECF 44,F 002E:BTFSC 44.6 002F:GOTO 034
ch = (ch + 7) & (~64);
0030:MOVLW 07 0031:ADDWF 44,W 0032:ANDLW BF 0033:MOVWF 44
}// endif
ch -= 54;
0034:MOVLW 36 0035:SUBWF 44,F
[编辑最佳解决方案]
按照@GJ 的建议优化现有解决方案。在 C 中,执行ch += 7; ch &= (~64);
而不是ch = (ch + 7) & (~64);
保存 1 指令。无需ch
在if()
.