When adding an integer n to pointer2 (16-bit unsigned number) and comparing it to pointer1, the following z80 assembly code is used:Andrey
ld l, (ix+6)
ld h, (ix+7)
inc hl
ld a, l
and 0feh
ld l, a
ld a, h
ld (ix+6), l
ld (ix+7), h
ld de, (pointer2)
add hl, de
ex de, hl
ld hl, (pointer1)
call wrelop
jr nc, label1
Most likely this is done to prevent a possible overflow when adding in a 16-bit processor register.
Maybe someone has come across a similar one and knows how these actions can be programmed in C.
Andrey
When adding an integer n to pointer2 (16-bit unsigned number) and comparing it to pointer1, the following z80 assembly code is used:Andrey
ld l, (ix+6)
ld h, (ix+7)
inc hl
ld a, l
and 0feh
ld l, a
ld a, h
ld (ix+6), l
ld (ix+7), h
ld de, (pointer2)
add hl, de
ex de, hl
ld hl, (pointer1)
call wrelop
jr nc, label1
Most likely this is done to prevent a possible overflow when adding in a 16-bit processor register.
Maybe someone has come across a similar one and knows how these actions can be programmed in C.
Andrey
On Tuesday, October 12, 2021 at 3:40:22 PM UTC-4, nikiti...@gmail.com wrote:
When adding an integer n to pointer2 (16-bit unsigned number) and comparing it to pointer1, the following z80 assembly code is used:
ld l, (ix+6)
ld h, (ix+7)
inc hl
ld a, l
and 0feh
ld l, a
ld a, h
ld (ix+6), l
ld (ix+7), h
ld de, (pointer2)
add hl, de
ex de, hl
ld hl, (pointer1)
call wrelop
jr nc, label1
Most likely this is done to prevent a possible overflow when adding in a 16-bit processor register.
Maybe someone has come across a similar one and knows how these actions can be programmed in C.
AndreyAndrey
Anyway, there is no overflow here at all -- what is the type of pointer2? Note that if p is a pointer, p+n
is numeric p + (n * sizeof(*p)): in other words, this calculation:
char *p2 = (char *)p;
p = p + (n * sizeof(*p));
p2 = (void *)p;
Now, it looks like ix+6 and ix+7 are the "n", appears to do n + 1, and then makes it an even number (and 0feh)
Can I see the C source for this production?
Note that ova.c that I pointed you at earlier does overflow detection for C arithmetic. And it works on both Hi-Tech C
on the Z80, and GCC on modern platforms. It is reasonably efficient on both of those. Note that carry is returned by the
add/subtract, and overflow is detected after the add/subtract.
FredW
среда, 13 октября 2021 г. в 03:57:16 UTC+3, fridtjof.ma...@gmail.com:Andrey
On Tuesday, October 12, 2021 at 3:40:22 PM UTC-4, nikiti...@gmail.com wrote:
When adding an integer n to pointer2 (16-bit unsigned number) and comparing it to pointer1, the following z80 assembly code is used:
ld l, (ix+6)
ld h, (ix+7)
inc hl
ld a, l
and 0feh
ld l, a
ld a, h
ld (ix+6), l
ld (ix+7), h
ld de, (pointer2)
add hl, de
ex de, hl
ld hl, (pointer1)
call wrelop
jr nc, label1
Most likely this is done to prevent a possible overflow when adding in a 16-bit processor register.
Maybe someone has come across a similar one and knows how these actions can be programmed in C.
AndreyAndrey
Anyway, there is no overflow here at all -- what is the type of pointer2? Note that if p is a pointer, p+n
is numeric p + (n * sizeof(*p)): in other words, this calculation:
char *p2 = (char *)p;
p = p + (n * sizeof(*p));
p2 = (void *)p;
Now, it looks like ix+6 and ix+7 are the "n", appears to do n + 1, and then makes it an even number (and 0feh)
Can I see the C source for this production?
Note that ova.c that I pointed you at earlier does overflow detection for C arithmetic. And it works on both Hi-Tech C
on the Z80, and GCC on modern platforms. It is reasonably efficient on both of those. Note that carry is returned by the
add/subtract, and overflow is detected after the add/subtract.
FredWThis is the memory allocation function:
The recreated C code is as follows:
char * alloc_mem (int size) {
char * l1;
register char * st;
if (word_707a <(word_7082 + (size = (size + 1) & 0xFE))) {
if ((word_7082 = sbrk (512)) == (char *) - 1)
pr_error ("Out of memory in% s", name_fun);
word_707a = sbrk (0);
}
st = word_7082;
word_7082 + = size;
l1 = st;
while (size--! = 0) * (l1 ++) = 0; // Clearing the allocated memory area return st;
}
However, the first if statement in this function generates code that is different from the one in the executable image.
I cannot understand why these actions (size = (size + 1) & 0xFE) and how important they are.
Andrey
среда, 13 октября 2021 г. в 03:57:16 UTC+3, fridtjof.ma...@gmail.com:Andrey
On Tuesday, October 12, 2021 at 3:40:22 PM UTC-4, nikiti...@gmail.com wrote:
When adding an integer n to pointer2 (16-bit unsigned number) and comparing it to pointer1, the following z80 assembly code is used:
ld l, (ix+6)
ld h, (ix+7)
inc hl
ld a, l
and 0feh
ld l, a
ld a, h
ld (ix+6), l
ld (ix+7), h
ld de, (pointer2)
add hl, de
ex de, hl
ld hl, (pointer1)
call wrelop
jr nc, label1
Most likely this is done to prevent a possible overflow when adding in a 16-bit processor register.
Maybe someone has come across a similar one and knows how these actions can be programmed in C.
AndreyAndrey
Anyway, there is no overflow here at all -- what is the type of pointer2? Note that if p is a pointer, p+n
is numeric p + (n * sizeof(*p)): in other words, this calculation:
char *p2 = (char *)p;
p = p + (n * sizeof(*p));
p2 = (void *)p;
Now, it looks like ix+6 and ix+7 are the "n", appears to do n + 1, and then makes it an even number (and 0feh)
Can I see the C source for this production?
Note that ova.c that I pointed you at earlier does overflow detection for C arithmetic. And it works on both Hi-Tech C
on the Z80, and GCC on modern platforms. It is reasonably efficient on both of those. Note that carry is returned by the
add/subtract, and overflow is detected after the add/subtract.
FredWThis is the memory allocation function:
The recreated C code is as follows:
char * alloc_mem (int size) {
char * l1;
register char * st;
if (word_707a <(word_7082 + (size = (size + 1) & 0xFE))) {
if ((word_7082 = sbrk (512)) == (char *) - 1)
pr_error ("Out of memory in% s", name_fun);
word_707a = sbrk (0);
}
st = word_7082;
word_7082 + = size;
l1 = st;
while (size--! = 0) * (l1 ++) = 0; // Clearing the allocated memory area return st;
}
However, the first if statement in this function generates code that is different from the one in the executable image.
I cannot understand why these actions (size = (size + 1) & 0xFE) and how important they are.
Andrey
On Wednesday, October 13, 2021 at 7:10:23 AM UTC-4, nikiti...@gmail.com wrote:
среда, 13 октября 2021 г. в 03:57:16 UTC+3, fridtjof.ma...@gmail.com:
On Tuesday, October 12, 2021 at 3:40:22 PM UTC-4, nikiti...@gmail.com wrote:
When adding an integer n to pointer2 (16-bit unsigned number) and comparing it to pointer1, the following z80 assembly code is used:
ld l, (ix+6)
ld h, (ix+7)
inc hl
ld a, l
and 0feh
ld l, a
ld a, h
ld (ix+6), l
ld (ix+7), h
ld de, (pointer2)
add hl, de
ex de, hl
ld hl, (pointer1)
call wrelop
jr nc, label1
Most likely this is done to prevent a possible overflow when adding in a 16-bit processor register.
Maybe someone has come across a similar one and knows how these actions can be programmed in C.
AndreyAndrey
Anyway, there is no overflow here at all -- what is the type of pointer2? Note that if p is a pointer, p+n
is numeric p + (n * sizeof(*p)): in other words, this calculation:
char *p2 = (char *)p;
p = p + (n * sizeof(*p));
p2 = (void *)p;
Now, it looks like ix+6 and ix+7 are the "n", appears to do n + 1, and then makes it an even number (and 0feh)
Can I see the C source for this production?
Note that ova.c that I pointed you at earlier does overflow detection for C arithmetic. And it works on both Hi-Tech C
on the Z80, and GCC on modern platforms. It is reasonably efficient on both of those. Note that carry is returned by the
add/subtract, and overflow is detected after the add/subtract.
FredWThis is the memory allocation function:
The recreated C code is as follows:
char * alloc_mem (int size) {
char * l1;
register char * st;
if (word_707a <(word_7082 + (size = (size + 1) & 0xFE))) {
if ((word_7082 = sbrk (512)) == (char *) - 1)
pr_error ("Out of memory in% s", name_fun);
word_707a = sbrk (0);
}
st = word_7082;
word_7082 + = size;
l1 = st;
while (size--! = 0) * (l1 ++) = 0; // Clearing the allocated memory area return st;
}
However, the first if statement in this function generates code that is different from the one in the executable image.
I cannot understand why these actions (size = (size + 1) & 0xFE) and how important they are.
AndreyAndrey
Was the peephole optimizer used? It looks like a production was removed:
mov a,h
and 0ffh
mov h,a
is "missing" -- note that *if* the code were actually &0xFE, it should have been:
mov a,l
and 0feh
mov l,a
mov h,0
(or something along those lines)
or, the compiler code generator is smart enough to deal with converting word into byte as needed.
FredW
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 285 |
Nodes: | 16 (2 / 14) |
Uptime: | 71:32:54 |
Calls: | 6,488 |
Calls today: | 1 |
Files: | 12,096 |
Messages: | 5,275,631 |