tags:

views:

194

answers:

3

Hi,

I would like to have this x86 ASM code ported to C or C++, as I don't understand ASM =)

Searching Google it seams Relogix and IDA Pro can do it. But I don't suppose they are cheap, given I only have this one source.

Understanding the math or the algorithm how it works would be just as good, as I am going to use OpenGL anyway.

Are there other methods?

;
;  a n d r o m e d a 
;                        
;  a 256b demo
;  by insomniac/neon
;
code    SEGMENT
    ASSUME  CS:code, DS:code
    p386
    LOCALS

ORG 100h

max =   4096
maxZ    =   5000

b   EQU byte ptr

Start:  lea di,vars
    mov ch,60
    rep stosw

    mov al,13h
    int 10h

p    al:    mov al,cl
    mov dx,3c8h
    out dx,al
    inc dx
    cmp al,64
    jb  b64_1
    mov al,63
b64_1:  out dx,al
    mov al,cl
    shr al,1
    out dx,al
    out dx,al
    loop    pal


.main:  push    8000h
    pop ES

    mov si,max

.loop:  mov ax,Z[si]
    cmp ax,maxZ-(maxZ/4)
    jg  NewStar
    cmp ax,2
    jg  Zok
NewStar:
    mov ax,bp
    mov X[si],ax

    imul    ax,8405h
    inc ax
    mov bp,ax

    shr ax,6
    sub ax,400
    mov Y[si],ax

    mov Z[si],maxZ-(maxZ/2)

Zok:    mov ax,X[si]
    movsx   dx,ah
    shl ax,8

    mov cx,Z[si]

    idiv    cx
    add ax,320/2
    cmp ax,320-1
    jge NewStar
    cmp ax,1
    jle NewStar

    mov di,ax

    mov ax,Y[si]
    movsx   dx,ah
    shl ax,8
    idiv    cx
    add ax,200/2

    imul    ax,320
    add di,ax

    mov al,127
    stosb

    mov ax,X[si]
    cmp ax,00
    jge .add
    neg ax
    shr ax,6
    add Y[si],ax
    jmp .notadd
.add:   shr ax,6
    sub Y[si],ax
.notadd:
    add Z[si],ax
    mov ax,Y[si]
    sar ax,3
    add X[si],ax

.NextStar:
    dec si
    dec si
    jnz .loop

    push    DS
    push    ES
    pop DS

    xor di,di
    xor cx,cx
.blur:  movzx   ax,DS:[di]
    movzx   dx,DS:[di+1]
    add ax,dx
    mov dl,DS:[di-320]
    add ax,dx
    mov dl,DS:[di+321]
    add ax,dx
    shr ax,2

    cmp al,0
    je  .skip
    dec ax

.skip:  stosb
    loop    .blur

    push    0a000h
    pop ES

    mov si,di
    mov ch,81h
    rep movsw

    pop DS

    mov dx,3dah
.vrt:   in  al,dx
    test    al,8
    jz  .vrt

    in  al,60h
    dec ax
    jnz .main

endprog:
    mov al,3
    int 10h

    ret

LABEL   vars
X   dw  max DUP (?)
Y   dw  max DUP (?)
Z   dw  max DUP (?)

code    ENDS
    END Start
+1  A: 

There are quite a few methods of doing so, for example this or this. ;-)

Gianni
Don't forget http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
Nathon
+9  A: 

In general case, this cannot be done. In this particular case, this cannot be done because this assembly program interacts with PC BIOS directly, using int 10h to turn on 320x200 256 VGA mode, and it interacts with PC hardware directly, by writing to IO ports 0x3c8 and 0x3c9 (this sets the VGA palette) and by reading from 0x3da (VGA status register) and 0x60 (PC keyboard microcontroller). It also writes directly to VGA video memory.

Under the conditions of executing on a PC-compatible computer with MS-DOS or similar OS (or, within a simulated environment such as dosbox), this can be done: you can either make each CPU register a C variable and each assembly mnemonic a C function that modifies those variables or writes at absolute memory addresses or IO ports (with outb() and inb()), or, and I think this would be a much more interesting task, understand the math this demo does, and implement that in a portable manner.

Either way, I haven't heard of tools that could do this automatically. Existing tools might handle simple logic, but understanding a demo is never an easy task! What automatic program can tell that

imul    ax,8405h
inc ax

should be replaced with ax = rand();?

Cubbi
Understanding the math or the algorithm how it works would be just as good, as I am going to use OpenGL anyway. Would a de-compiller be able to do a reasonable job at that? And yes, your 'rand()' example is scary =)
Sandra Schlichting
I wouldn't hold my hopes high, but it *may* give you a mysterious black box procedure that you'd use to calculate the frames. As long as you realize that the lines from `push 0a000h` to `jnz .main` copy the 320x200 image to video memory and pause for refresh before looping to calculate the next frame (unless a key is pressed). Like @John said, it's best to have someone do it by hand.
Cubbi
+5  A: 

You could throw it on RentaCoder and pay someone a few $ to write a C version by hand, including an annotation how it was done.

John
Huh, first time I ever got '+' for suggesting to pay someone else to do it for you :)
John
Yeah surprising. This is actually a nice idea for this case :P
Matt Joiner