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








"Walter" <walter digitalmars.com>