On Mon, 25 Feb 2002, Clarence Verge wrote:
<snip>
>
> That code you supplied dissambles to:
>
> MOV AX,0040
> PUSH AX
> POP DS
> MOV WORD PTR [0072],1234
> MOV AX,FFFF
> PUSH AX
> MOV AX,0000
> PUSH AX
> RETF
>
> Must have been written in "C". Really kinky. <G>
> Let's take the first three instructions:
> MOV AX,0040
> PUSH AX
> POP DS
>
> Why not replace this with:
> XOR AX,AX
> MOV DS,AX
>
> And then:
> MOV WORD PTR [0472],1234
> MOV BX,FFFF
> PUSH BX
> PUSH AX
> RETF
> ?
>
> Makes more sense to me.<g>
>
<snip>
>
> - - Clarence Verge
> - - Back to using Arachne V1.62 ....
>
> ------------------------------
>
This is a rather good example. The extra weight comes most probably from
the way the pointer was initialised (0040:0072 vs 0000:0472). I think this
can be tweaked by modifying some Borland C settings (segment alignment).
Could the push ax /pop ds sequence appear due to the fact that "mov
ds,ax" does not exist anymore in case of 286+ ?
In the mean time here are 2 more relevant examples about how much the code
can be optimized (or non-optimized) by the C compiler (and the author of
the program). Sorry again folks, if I annoy you, please just don't read
any further.
Example 1
==========
#include <stdio.h>
void main (void)
{
unsigned char *sir = "Hello World\n";
while (*sir!= '\0')
putchar (*sir++);
}
}
results in
.file "hello2.c"
.version "01.01"
gcc2_compiled.:
.section .rodata
.LC0:
.string "Hello World\n"
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp,%ebp
pushl %ebx
movl $.LC0,%ebx
cmpb $0,.LC0
je .L18
.p2align 4,,7
.L19:
movzbl (%ebx),%eax
incl %ebx
pushl stdout
pushl %eax
call _IO_putc
addl $8,%esp
cmpb $0,(%ebx)
jne .L19
.L18:
movl -4(%ebp),%ebx
leave
ret
.Lfe1:
.size main,.Lfe1-main
.ident "GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2
release)"
_IO_putc is a macro defined elsewhere. Its arguments have to be pushed
onto the stack (an int and a file pointer). Note the use of putc instead
of putchar. Putc returns an int casted to a char. Note that everything is
32 bits. I suspect they take too much care of ebx register here :-)
int
Example 2
=========
Uses a static variable. Even if
it is not necessary, the compiler takes care of "sir" at every iteration.
The recipe is the same, though:
#include <stdio.h>
unsigned char *sir = "Hello World\n";
void main (void)
{
while (*sir!= '\0')
putchar (*sir++);
}
---------------------
.file "hello2.c"
.version "01.01"
gcc2_compiled.:
.globl sir
.section .rodata
.LC0:
.string "Hello World\n"
.data
.align 4
.type sir,@object
.size sir,4
sir:
.long .LC0
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp,%ebp
jmp .L22
.p2align 4,,7
.L19:
movzbl (%eax),%eax
incl sir
pushl stdout
pushl %eax
call _IO_putc
addl $8,%esp
.L22:
movl sir,%eax
cmpb $0,(%eax)
jne .L19
leave
ret
.Lfe1:
.size main,.Lfe1-main
.ident "GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2
release)"
Cristian Burneci
- The challenge Clarence Verge
- Re: The challenge Guenter Bietzig
- Re: The challenge Bastiaan Edelman, PA3FFZ
- Re: The challenge Bastiaan Edelman, PA3FFZ
- Re: The challenge Clarence Verge
- Re: The challenge Cristian Burneci
- Re: The challenge Clarence Verge
- Re: The challenge Glenn McCorkle
- Re: The challenge Glenn McCorkle
- Re: The challenge Clarence Verge
- Re: The challenge Clarence Verge
- Re: The challenge Cristian Burneci
- Re: The challenge Clarence Verge
- Re: The challenge Kali McLaughlin
- Re: The challenge Clarence Verge
- Re: The challenge Glenn McCorkle
