c++.dos.16-bits - Bug...? register variable CX is used for shifting another register variable SI.
- "Kiyuki" <sakura tennodai.com> Jul 16 2001
- Heinz Saathoff <hsaat bre.ipnet.de> Jul 16 2001
- "Kiyuki" <sakura tennodai.com> Jul 16 2001
- Heinz Saathoff <hsaat bre.ipnet.de> Jul 17 2001
- "Walter" <walter digitalmars.com> Jul 17 2001
Hello, I'm encountered sc's bug which uses register CX as a register variable, but CL is used for another register. These are fragments of C++ code and obj2asm's output. The variable lo is assigned to register CX, but CL is used to shift SI with 8bit. So CX's value is rotten. Thanks. // bug.cpp class text12 { public: char far* _f3; char far* _image; char buf[18]; int zenkanji2(unsigned code); }; int text12::zenkanji2(unsigned code) { int k; if (! _f3) return 0; unsigned hi; if (0x989f <= code && code <= 0x9ffe) { hi = ((code / 0x100) - 0x98) & 0xff; } else if (0xe040 <= code && code <= 0xeaa4) { hi = ((code / 0x100) - (0x98 + 0x40)) & 0xff; } else { return 0; } unsigned lo = code & 0x00ff; if (0x40 <= lo && lo < 0x7f) { lo -= 0x40; } else if (0x7f < lo && lo <= 0xfc) { lo -= 0x41; } else { return 0; } unsigned offset = (hi*188 + lo - 94); offset *= 18; for (k = 0; k < 18; k++) { _image[k] = _f3[offset + k]; } return 1; } // --------------------- c:\> sc -c -msw -NL -j0 -a1 -0 -o+space -Bj -Ab -Aa -gl -e -s bug.cpp c:\> obj2asm bug _TEXT segment word use16 public 'CODE' ;size is 201 _TEXT ends _DATA segment word use16 public 'DATA' ;size is 0 _DATA ends CONST segment word use16 public 'CONST' ;size is 0 CONST ends _BSS segment word use16 public 'BSS' ;size is 0 _BSS ends DGROUP group _DATA,CONST,_BSS extrn __chkstk public ?zenkanji2 text12 QACHI Z _TEXT segment assume CS:_TEXT ; ;class text12 { ;public: ; char far* _f3; ; char far* _image; ; char buf[18]; ; int zenkanji2(unsigned code); ;}; ; ;int text12::zenkanji2(unsigned code) { ?zenkanji2 text12 QACHI Z: push BP mov BP,SP mov AX,2 call near ptr __chkstk push SI push DI mov CX,6[BP] mov DX,4[BP] ; int k; ; if (! _f3) return 0; mov BX,DX mov AX,2[BX] or AX,[BX] je L75 ; ; unsigned hi; ; if (0x989f <= code && code <= 0x9ffe) { cmp CX,0989Fh jb L37 cmp CX,09FFEh ja L37 ; hi = ((code / 0x100) - 0x98) & 0xff; mov SI,CX mov CX,8 ;;;;;;;;;;;;; HERE HERE ;;;;;;;;;;;; shr SI,CL add SI,0FF68h and SI,0FFh jmp short L52 ; } else if (0xe040 <= code && code <= 0xeaa4) { L37: cmp CX,0E040h jb L75 cmp CX,0EAA4h ja L75 ; hi = ((code / 0x100) - (0x98 + 0x40)) & 0xff; mov SI,CX mov CX,8 ;;;;;;;;;;;;; HERE HERE ;;;;;;;;;;;; shr SI,CL add SI,0FF28h and SI,0FFh ; } else { ; return 0; ; } ; ; unsigned lo = code & 0x00ff; ; ; if (0x40 <= lo && lo < 0x7f) { L52: mov BX,CX ;;;;;;;;;;;;; HERE HERE ;;;;;;;;;;;; xor BH,BH cmp BX,040h jb L65 cmp BX,07Fh jae L65 ; lo -= 0x40; add BX,0FFFFFFC0h jmp short L7F ; } else if (0x7f < lo && lo <= 0xfc) { L65: cmp BX,07Fh jbe L75 cmp BX,0FCh ja L75 ; lo -= 0x41; add BX,0FFFFFFBFh jmp short L7F L75: xor AX,AX pop DI pop SI mov SP,BP pop BP ret 4 L7F: mov 4[BP],DX ; } else { ; return 0; ; } ; ; unsigned offset = (hi*188 + lo - 94); mov AX,SI mov CL,0BCh mul CX mov DI,AX add DI,BX add DI,0FFFFFFA2h ; offset *= 18; mov AX,012h mul DI mov DI,AX ; ; for (k = 0; k < 18; k++) { mov word ptr -2[BP],0 mov DX,4[BP] mov CX,-2[BP] jmp short LB9 ; _image[k] = _f3[offset + k]; LA3: mov AX,DI add AX,CX mov BX,DX les SI,[BX] add SI,AX mov AL,ES:[SI] les BX,4[BX] add BX,CX mov ES:[BX],AL ; } inc CX LB9: cmp CX,012h jb LA3 ; ; return 1; mov AX,1 ;} pop DI pop SI mov SP,BP pop BP ret 4 _TEXT ends _DATA segment _DATA ends CONST segment CONST ends _BSS segment _BSS ends end Compilation finished at Tue Jul 17 00:35:12
Jul 16 2001
Kiyuki schrieb...Hello, I'm encountered sc's bug which uses register CX as a register variable, but CL is used for another register. These are fragments of C++ code and obj2asm's output. The variable lo is assigned to register CX, but CL is used to shift SI with 8bit. So CX's value is rotten.
Even if I haven't fully analyzed the code it seems to be ok because the compiler moves the old value of CX to SI _before_ it assigns a shift count to CX.[snip] ja L37 ; hi = ((code / 0x100) - 0x98) & 0xff; mov SI,CX
here CX is move to SImov CX,8 ;;;;;;;;;;;;; HERE HERE ;;;;;;;;;;;; shr SI,CL add SI,0FF68h and SI,0FFh jmp short L52
Shift's and masks are done with SI I've noticed that SC often rearanges register values. But this is absolute legal and no error! Regards, Heinz
Jul 16 2001
In sample source, variables are assigned code -> CX, hi -> SI, lo -> BX. Code fragment of this sample: hi = ((code/0x100) - 0x98) & 0xff; (1) lo = code & 0xff; (2) if (0x40 <= lo && lo < 0x7f) { ... (3) Statement (1) is compiled to mov SI,CX mov CX,8 shr SI,CL add SI,0xff68h and SI,0ffh It seems good, indeed. But register CX is changed to 8; so the value of the variable code is 8 which I don't expected. Statements (2), (3) are compiled to mov BX,CX xor BH,BH cmp BX,040h jb L65 cmp BX,07fh jae L65 ... When this code runs, the variable lo is always 8, because the register variable CX is assigned to 8.Even if I haven't fully analyzed the code it seems to be ok because the compiler moves the old value of CX to SI _before_ it assigns a shift count to CX.
Thanks,
Jul 16 2001
Kiyuki schrieb...Code fragment of this sample: hi = ((code/0x100) - 0x98) & 0xff; (1) lo = code & 0xff; (2) if (0x40 <= lo && lo < 0x7f) { ... (3) Statement (1) is compiled to mov SI,CX mov CX,8 shr SI,CL add SI,0xff68h and SI,0ffh
Till here it's ok you say.It seems good, indeed. But register CX is changed to 8; so the value of the variable code is 8 which I don't expected. Statements (2), (3) are compiled to mov BX,CX xor BH,BH cmp BX,040h jb L65 cmp BX,07fh jae L65 ... When this code runs, the variable lo is always 8, because the register variable CX is assigned to 8.
You're right, haven't seen this in my previous post. This is indeed wrong code as CX isn't the value of 'code' anymore. It's a code generation or optimizer bug. Regards, Heinz
Jul 17 2001
It is a bug, and I've sent Kiyuki a fix. Next time I post a new version, it'll incorporate the fix. -Walter Heinz Saathoff wrote in message ...Kiyuki schrieb...Code fragment of this sample: hi = ((code/0x100) - 0x98) & 0xff; (1) lo = code & 0xff; (2) if (0x40 <= lo && lo < 0x7f) { ... (3) Statement (1) is compiled to mov SI,CX mov CX,8 shr SI,CL add SI,0xff68h and SI,0ffh
Till here it's ok you say.It seems good, indeed. But register CX is changed to 8; so the value of the variable code is 8 which I don't expected. Statements (2), (3) are compiled to mov BX,CX xor BH,BH cmp BX,040h jb L65 cmp BX,07fh jae L65 ... When this code runs, the variable lo is always 8, because the register variable CX is assigned to 8.
You're right, haven't seen this in my previous post. This is indeed wrong code as CX isn't the value of 'code' anymore. It's a code generation or optimizer bug. Regards, Heinz
Jul 17 2001