汉气猗亡
镜像:https://leisurebamboo.wordpress.com/2023/10/06/tc2
汉气猗亡——汉化 turbo c 2.01 札记·完蛋日·祭念borland·杂感。
原文在2010-1-1 发表于 http://www.aogosoft.com/bbs/view.asp?id=89992 ,现有增删。
"汉化"(Sinicization)暂定义为“函数名、变量名、宏名 能用汉字”。
完蛋日。杂感。borland忘却的纪念。
borland的IDE部门被分割、卖出未逾一年,borland已被focus收购了,我也有写一点东西的必要了。
这次的汉化,选的是Turbo c 2.01版,可在
http://edn.embarcadero.com/museum/内找到。通过链接
http://cc.codegear.com/Free/tc201,可以得到
http://altd.embarcadero.com/download/museum/tc201.zip
(看到 embarcadero 这個词,回想borland当年,唏嘘不已)。
其内含有 2.01版的tcc.exe,长度为 18'0385字节。
㈠将该exe文件的 2a506h~2a585h 偏移处的内容,由原来的80h个“EE”改为80h个“F6”;
将该exe文件的 2a606h~2a685h 偏移处的内容,由原来的80h个“E6”改为80h个“F6”
(更改理由见附录①),即可实现汉字函数名、变量名的正常编译。
㈡.将该exe文件的 2c00dh~2c08ch 偏移处的内容,由原来的80h个“00”改为80h个“08”(更改理由见附录②),
宏的左半阕(例如 #define 汉字 abc)即可使用汉字。
㈢.将该exe文件的 19d85h~19da1h 偏移处的内容,
由原来的 “8C 46 FE, 89 5E FC 33, F6 EB 04 FF
46 FC 46 C4, 5E FC 26 80, 3F 00 74 06, 26 F6 07 80
74 ED”
改为 “31 F6 26, 8A 07 08 C0, 74 0E 79 08
3C 90 72 08, 3C FC 73 04, 46 43 EB EB, 8C 46 FE 89
5E FC”(更改理由见附录③),
宏的右半阕(例如 #define inc 汉字++ )即可使用汉字。
㈣.将该exe文件的 1a084h~1a0b3h 偏移处的内容,
由原来的 “8B 56 FA 8B, C3 3B 16 B6, 74 75 16 3B
06 B4 74 75, 10 C4 5E F4, 8C 06 3A 50, 89 1E 38 50
EB 03 FF 46, F4 C4 5E F4, 26 80 3F 00, 74 06 26 F6
07 80 74 EE”
改为“66 8B 46 F8, C4 5E F4 66, 3B 06 B4 74
75 08 8C 06, 3A 50 89 1E, 38 50 26 8A, 07 0A C0 74
0D 79 08 3C, 90 72 07 3C, FC 73 03 43, EB EC 89 5E
F4 90 90 90” (更改理由见附录④),以免取词出错。
㈤.改完了。
至此,tcc.exe 2.01 版本汉化完毕,函数名、变量名、宏 均能用汉字。但为便于日後tc编译链接,命名时请仍沿用下划线 或英文字母开头。
本文的反响,可能是芸芸的在校学子感觉受到了蛊惑(因为不少高校仍沿用turbo c教学)。但如我旧贴所说,更多的肯定是“前辈的不齿、同侪的嘲讽、后学的误解”。
编译器的生命,毕竟受到商业推动的影响。也祗有商业产品,才会提供足够的文档、用例、在线帮助,并对广大的用户群形成吸引力、赢取其对产品的预期信心。但商业过程通常与产品质量关系不大,对程序员而言最可怕者也是这一点,他们祗能将宝压在大公司身上。
然而,即使强如borland这般的强者,也居然垮了。敢于反抗“雷蒙德的暴君”的队伍中,骤然失去了一面(哪怕仅仅是精神上的)旗帜。
思之黯然,遂有本文悲观的题目。
以下是 更改tcc.exe的原因 与 所涉的反汇编代码。各位 觉得它厌烦的读贴人士,请关闭本窗口。
具体的asm,可参阅https://sourceforge.net/projects/difc/files/turbo_c/2.0/
附录:
①tcc.exe的编译部分为:
其中 wo[50D4]==30B6h,为《分枝枚举表》首址,内共有100h个字节,取值从-19h(0e7h)到29h 不等。其详细内容为:
将《分枝枚举表》的後半阕(即ds:3136h~31b5h的内容,对应为本exe文件的 2a506h~2a585h 偏移处的内容),
改作80h个“在表中常见的”f6,即可实现汉字函数名、变量名的正常编译。
但当 wo[50D4]==31B6h 时,《分枝枚举表》的後半阕(即ds:3236h~32b5h的内容,对应为本exe文件的 2a606h~2a685h 偏移处的内容),
就成了db 80h dup(0E6h),亦须改作80h个“在表中常见的”f6。
②宏定义时的strcpy函数片段为:
其中ds:[4bbd~4cbc] 为《宏内ascii码对应属性表》,其具体内容为:
汉字的属性在 ds:[4c3d~4cbc]内。原文的该部分为全零,导致“宏的名含有汉字”时定义出错。
汉化方法仍是将ascii(80~FF)的对应属性部分(位于tcc.exe的第[2c00dh~2c08ch]字节,原文为80h个“00”),换为80h dup(8),即可实现汉字宏名的正常编译。
③而宏替换时调用的strlen函数片段为:
在39c的那一句 会 导致“宏的内容含有汉字”时会替换出错。
拟整段改为:
④而取另一词调用的next_word函数片段为:
若有某字符>=80,则断句出错。
拟改作:
回想borland当年,雄姿英发。多少次与微软浴血奋战,
如许力求完美的编译速度、和集成开发环境。让无数程序员
祗要一想到Borland,就油然而生出一股朝圣般的孺慕和崇敬。
其多平台开发工具的用户达到320多万,遍及29个以上的国家。
JBuilder、Java开发工具、Delphi与C++Builder、研发出来
未久的PHP与Ruby的IDE开发工具……还有本文提及的Turbo C。
往昔的辉煌,去岁出卖了IDE部门,今年卖了自己。
覆辙重蹈,何其之促。美人迟暮,英雄末路。
难道这就是x86商业编译器的下场吗?难道大家都要退到
单片机或者开源的战线上去了吗?
默哀一分钟……
汉气猗亡——汉化 turbo c 2.01 札记·完蛋日·祭念borland·杂感。
原文在2010-1-1 发表于 http://www.aogosoft.com/bbs/view.asp?id=89992 ,现有增删。
"汉化"(Sinicization)暂定义为“函数名、变量名、宏名 能用汉字”。
完蛋日。杂感。borland忘却的纪念。
borland的IDE部门被分割、卖出未逾一年,borland已被focus收购了,我也有写一点东西的必要了。
这次的汉化,选的是Turbo c 2.01版,可在
http://edn.embarcadero.com/museum/内找到。通过链接
http://cc.codegear.com/Free/tc201,可以得到
http://altd.embarcadero.com/download/museum/tc201.zip
(看到 embarcadero 这個词,回想borland当年,唏嘘不已)。
其内含有 2.01版的tcc.exe,长度为 18'0385字节。
㈠将该exe文件的 2a506h~2a585h 偏移处的内容,由原来的80h个“EE”改为80h个“F6”;
将该exe文件的 2a606h~2a685h 偏移处的内容,由原来的80h个“E6”改为80h个“F6”
(更改理由见附录①),即可实现汉字函数名、变量名的正常编译。
㈡.将该exe文件的 2c00dh~2c08ch 偏移处的内容,由原来的80h个“00”改为80h个“08”(更改理由见附录②),
宏的左半阕(例如 #define 汉字 abc)即可使用汉字。
㈢.将该exe文件的 19d85h~19da1h 偏移处的内容,
由原来的 “8C 46 FE, 89 5E FC 33, F6 EB 04 FF
46 FC 46 C4, 5E FC 26 80, 3F 00 74 06, 26 F6 07 80
74 ED”
改为 “31 F6 26, 8A 07 08 C0, 74 0E 79 08
3C 90 72 08, 3C FC 73 04, 46 43 EB EB, 8C 46 FE 89
5E FC”(更改理由见附录③),
宏的右半阕(例如 #define inc 汉字++ )即可使用汉字。
㈣.将该exe文件的 1a084h~1a0b3h 偏移处的内容,
由原来的 “8B 56 FA 8B, C3 3B 16 B6, 74 75 16 3B
06 B4 74 75, 10 C4 5E F4, 8C 06 3A 50, 89 1E 38 50
EB 03 FF 46, F4 C4 5E F4, 26 80 3F 00, 74 06 26 F6
07 80 74 EE”
改为“66 8B 46 F8, C4 5E F4 66, 3B 06 B4 74
75 08 8C 06, 3A 50 89 1E, 38 50 26 8A, 07 0A C0 74
0D 79 08 3C, 90 72 07 3C, FC 73 03 43, EB EC 89 5E
F4 90 90 90” (更改理由见附录④),以免取词出错。
㈤.改完了。
至此,tcc.exe 2.01 版本汉化完毕,函数名、变量名、宏 均能用汉字。但为便于日後tc编译链接,命名时请仍沿用下划线 或英文字母开头。
本文的反响,可能是芸芸的在校学子感觉受到了蛊惑(因为不少高校仍沿用turbo c教学)。但如我旧贴所说,更多的肯定是“前辈的不齿、同侪的嘲讽、后学的误解”。
编译器的生命,毕竟受到商业推动的影响。也祗有商业产品,才会提供足够的文档、用例、在线帮助,并对广大的用户群形成吸引力、赢取其对产品的预期信心。但商业过程通常与产品质量关系不大,对程序员而言最可怕者也是这一点,他们祗能将宝压在大公司身上。
然而,即使强如borland这般的强者,也居然垮了。敢于反抗“雷蒙德的暴君”的队伍中,骤然失去了一面(哪怕仅仅是精神上的)旗帜。
思之黯然,遂有本文悲观的题目。
以下是 更改tcc.exe的原因 与 所涉的反汇编代码。各位 觉得它厌烦的读贴人士,请关闭本窗口。
具体的asm,可参阅https://sourceforge.net/projects/difc/files/turbo_c/2.0/
附录:
①tcc.exe的编译部分为:
cs:077 | 268A07 B400 | AL=ES:[BX],AH=0;即c=fgetch() |
cs:07C | 8946FC | [BP-04]=AX |
cs:07F | 8B1ED450 | BX=wo[50D4];分枝枚举表==30B6h |
cs:083 | 035EFC | + wo[BP-4] |
cs:086 | 8A07 | AL=[BX];即enum=分枝枚举表[c] |
cs:088 | 98 8946FE | CBW, [BP-02]=AX |
cs:08C | 2DE0FF | AX+=20 |
cs:08F | 3D2000 7603 E9F800 | if(AX>=20)JMP 018F |
cs:097 | 8BD8 D1E3 | BX=AX<<1 |
cs:09B | 2E FFA7A000 | JMP CS:00A0[BX] |
其中 wo[50D4]==30B6h,为《分枝枚举表》首址,内共有100h个字节,取值从-19h(0e7h)到29h 不等。其详细内容为:
db 8 dup(0EEh) | ;00~07 |
db 0EEh,4 dup(-9),0ech,2 dup(0EEh) | ;08~0F |
db 8 dup(0EEh) | ;10~17 |
db 2 dup(0EEh),0E7h,5 dup(0EEh) | ;18~1f |
db -9,0,0F4h,2 dup(0EEh),-1,-2,0F2h | ;20~27 |
db 1,2,-3,-4,8,0F1h,0F0h,-5 | ;28~2f |
db 0Ah dup(0F5h) | ;'0' ~ '9' |
db 1Fh,7,0EFh,0F8h,0EDh,1Eh | ;3A~3F |
db 0EEh,1Ah dup(0F6h) | ;'@', 'A'~'Z' |
db 3, 0EAh,4, 0FAh, 0F6h | ;5B~5F |
db 0EEh,1Ah dup(0F6h) | ;60, 'a'~'z' |
db 5, 0F9h,6, 29h, 0EEh | ;7B~7F |
db 80h dup(0EEh) | ;80~FF |
将《分枝枚举表》的後半阕(即ds:3136h~31b5h的内容,对应为本exe文件的 2a506h~2a585h 偏移处的内容),
改作80h个“在表中常见的”f6,即可实现汉字函数名、变量名的正常编译。
但当 wo[50D4]==31B6h 时,《分枝枚举表》的後半阕(即ds:3236h~32b5h的内容,对应为本exe文件的 2a606h~2a685h 偏移处的内容),
就成了db 80h dup(0E6h),亦须改作80h个“在表中常见的”f6。
②宏定义时的strcpy函数片段为:
cs:B17 | A02424 | do{.... | |
cs:B27 | 8A4604 | AL=c; | //AL=[BP+04] |
cs:B2A | C45EFC | es:bx=dst; | //LES BX,[BP-4] |
cs:B2D | 268807 FF46FC | *(dst++)=AL; | //ES:[BX]=AL, wo[BP-4]++ |
... | |||
cs:B43 | C41E3850 | es:bx=src; | //LES BX,[5038] |
cs:B47 | FF063850 | src++; | //INC wo[5038] |
cs:B4B | 268A07 B400 | ax=*src; | //AL=ES:[BX],AH=00 |
cs:B50 | 894604 8B5E04 | c=ax; | //BX=[BP+04]=AX |
cs:B56 | F687BD4B0E 75BA | }while(attr[c]&0x0E | //TEST by 4BBD[BX],0E, JNZ B17 |
cs:B5D | 83FB5F 74B5 | || c=='_' | //CMP BX,5F, JZ B17 |
cs:B62 | 83FB24 74B0 | || c=='$'); | //CMP BX,24, JZ B17 |
其中ds:[4bbd~4cbc] 为《宏内ascii码对应属性表》,其具体内容为:
db 8 dup(20h) | ;00~07 |
db 20h,21h,21h | ;08~0A |
db 5 dup(20h) | ;0B~0F |
db 8 dup(20h) | ;10~17 |
db 8 dup(20h) | ;18~1F |
db 1,7 dup(0) | ;20~27 |
db 8 dup(0) | ;28~2F |
db 0Ah dup(2) | ;'0'~'9' |
db 6 dup(0) | ;3A~3F |
db 0,6 dup(14h) | ;'@',"ABCDEF" |
db 20 dup(4) | ;'G'~'Z' |
db 5 dup(0) | ;5B~5F |
db 0,6 dup(18h) | ;60,"abcdef" |
db 20 dup(8) | ;'g'~'z' |
db 4 dup(0) | ;7B~7E |
db 20h | ;7F |
db 80h dup(0) | ;80~FF |
汉字的属性在 ds:[4c3d~4cbc]内。原文的该部分为全零,导致“宏的名含有汉字”时定义出错。
汉化方法仍是将ascii(80~FF)的对应属性部分(位于tcc.exe的第[2c00dh~2c08ch]字节,原文为80h个“00”),换为80h dup(8),即可实现汉字宏名的正常编译。
③而宏替换时调用的strlen函数片段为:
cs:385 | 8C46FE 895EFC | p=es:bx; | //[BP-2]=ES, [BP-4]=BX |
cs:38B | 33F6 EB04 | strlen=0; | //SI=0, JMP 0393 |
cs:393 | C45EFC | //LES BX,[BP-04] | |
cs:396 | 26803F00 7406 | while(p[0]!='\0' | //CMP by ES:[BX],00,JZ 3A2 |
cs:39C | 26F60780 74ED | && (p[0]&80h)==0) | //TEST by ES:[BX],80,JZ 38F |
cs:38F | FF46FC | {p++; | //INC wo[BP-04] |
cs:392 | 46 | strlen++; | //INC SI |
} | |||
cs:3A2 | C45EF4 | …… |
拟整段改为:
cs:385 | 31f6 | strlen=0; | //SI=0 |
cs:387 | 268A07 | do{ | //AL=ES:[BX] |
cs:38A | 08C0 740E | if(*p=='\0')break; | //OR AL,AL, JZ 39C |
cs:38E | 7908 | else if(p[0]&80h | // JNS 398 |
cs:390 | 3C90 7208 | &&(p[0]<90h) | //if(AL<90)JB 39C |
cs:394 | 3CFC 7304 | ||p[0]>=FCh))break; | //if(al>=FC)jae 39C |
cs:398 | 46 43 | else{strlen++; p++}; | //SI++, BX++ |
cs:39A | EBEF | }while(1); | //JMP 387 |
cs:39C | 8C46FE 895EFC | p=es:bx; | //[BP-2]=ES, [BP-4]=BX |
cs:3A2 | C45EF4 | …… |
④而取另一词调用的next_word函数片段为:
cs:684 | 8B56FA 8BC3 | //dx=[bp-06]; ax=bx | |
cs:689 | 3B16B674 7516 | if(lp8==g_74b6) | //cmp dx, [74B6], jne 6A5 |
cs:68F | 3B06B474 7510 | //cmp ax, [74B4], jne 6A5 | |
cs:695 | C45EF4 | { | //les bx, [bp-0C] |
cs:698 | 8C063A50 891E3850 | g_5038=lpC; | //[503A]=es; [5038]=bx |
cs:6A0 | EB03 | }; | //jmp 6A5 |
cs:6A5 | C45EF4 | //les bx, [bp-0C] | |
cs:6A8 | 26803F00 7406 | while(lpC[0]!='\0' | //cmp by es:[bx],00; je 6B4 |
cs:6AE | 26F60780 74EE | && (lpC[0]&80h)==0) | //test by es:[bx],80; je 6A2 |
cs:6A2 | FF46F4 | lpC++; | //inc wo[bp-0C] |
cs:6B4 | C45EF8 | …… |
拟改作:
cs:684 | 668B46F8 | //eax=lp8;//[bp-08] | |
cs:688 | C45EF4 | p=lpC; | //les bx,lpC |
cs:68B | 663B06B474 | if(lp8==g_74b6) | //cmp eax,[74B4] |
cs:690 | 7508 | //jne 69A | |
cs:692 | 8C063A50 | g_5038=lpC; | // [503A]=es |
cs:696 | 891E3850 | // [5038]=bx | |
cs:69A | 268A07 | do{ | //al=p[0];//es:[bx] |
cs:69D | 0AC0 740D | if(p[0]=='0')break; | //or al,al; je 6AE |
cs:6A1 | 7908 | else if(p[0]&80h | // jns 6AB |
cs:6A3 | 3C90 7207 | && (p[0]<90h | //cmp al,90; jb 6AE |
cs:6A7 | 3CFC 7303 | || p[0]>=FCh))break; | //cmp al,FC; jnb 6AE |
cs:6AB | 43 | else p++; | //inc bx |
cs:6AC | EBEC | }while(1); | //jmp 69A |
cs:6AE | 895EF4 | lpC=p; | //[bp-0C]=bx |
cs:6B1 | 90 90 90 | //nop | |
cs:6B4 | C45EF8 | …… |
回想borland当年,雄姿英发。多少次与微软浴血奋战,
如许力求完美的编译速度、和集成开发环境。让无数程序员
祗要一想到Borland,就油然而生出一股朝圣般的孺慕和崇敬。
其多平台开发工具的用户达到320多万,遍及29个以上的国家。
JBuilder、Java开发工具、Delphi与C++Builder、研发出来
未久的PHP与Ruby的IDE开发工具……还有本文提及的Turbo C。
往昔的辉煌,去岁出卖了IDE部门,今年卖了自己。
覆辙重蹈,何其之促。美人迟暮,英雄末路。
难道这就是x86商业编译器的下场吗?难道大家都要退到
单片机或者开源的战线上去了吗?
默哀一分钟……
评论
发表评论