Переменные сборки удалены (16 битная сборка x86) - PullRequest
0 голосов
/ 20 сентября 2018

Я все еще играю с ретро-программированием в Turbo C для MS-DOS, и я обнаружил некоторые проблемы с использованием переменных.

Если я определю некоторые переменные в начале кода сборки (в BSS или DATA), и попробуйте использовать их внутри функции сборки, в большинстве случаев эти переменные удаляются или в конечном итоге содержат случайные данные.

Я выучил немного сборки для игрового мальчика :) и переменные всегда работалину и никогда не были удалены или изменены, я думаю, x86 asm отличается.

Тогда я попробовал это с использованием встроенной сборки, и это было немного лучше, есть только одна переменная (ширина) не работает.

void draw_map_column(MAP map, TILE *t){
    word *tiledata = &t->data;
    int *mapdata = map.data;
    int width = map.width<<1;
    word tile_offset = 0;
    word map_offset = 0;
    word screen_offset = 0;
    asm{
        push ds
        push di
        push si

        mov     dx,12       //column

        lds     bx,[tiledata]                   
        lds     si,ds:[bx]              //ds:si data address
        mov     [tile_offset],ds
        mov     [tile_offset+2],si

        les     bx,[mapdata]
        mov     ax,es:[bx]
        mov     cl,8
        shl     ax,cl
        add     si,ax
        mov     di,screen_offset        //es:di screen address                          
    }
    loop_tile:
        asm{
        mov     ax,0A000h
        mov     es,ax
        mov     ax,16
    }
    copy_tile:  
    asm{
        mov     cx,8
        rep     movsw               
        add     di,320-16
        dec     ax
        jnz     copy_tile

        mov     ds,[tile_offset]
        mov     si,[tile_offset+2]

        mov     ax,map_offset
        add     ax,[width]        //"width" does never contain the value stored at the start
        mov     map_offset,ax

        les     bx,[mapdata]
        add     bx,ax
        mov     ax,es:[bx]
        mov     cl,8
        shl     ax,cl
        add     si,ax

        dec     dx
        jnz     loop_tile

        pop si
        pop di
        pop ds
}   

}

Просто обратите внимание на переменную "witdh", которая вообще не работает, если я заменю ее на число (40), код будет работать так, как ожидалось (это рисует столбец тайлов)используя массив карт, и некоторые плитки хранятся в оперативной памяти

Я думаю, это как-то связано с push / pop и т. Д., И что-то не так, как должно.

И что происходит в чистой сборке?ни одна из переменных не работала.Я определил их как DW, а также добавил:

push bp
mov bp,sp

;function 

mov sp,bp
pop bp

Спасибо.

1 Ответ

0 голосов
/ 20 сентября 2018

Хорошо, еще раз большое спасибо, в следующий раз я буду более терпеливым, прежде чем спрашивать.

На всякий случай, если это кому-то пригодится, я определил переменную, используя неправильный размер.Есть и другие вещи, которые можно улучшить, но это другой вопрос.

Переменная "tileoffset" содержит 32-битный адрес, поэтому это должно быть "слово", а не "слово".Тогда функция должна быть такой:

void draw_map_column(MAP map, TILE *t){
    word *tiledata = &t->data;
    int *mapdata = map.data;
    int width = map.width<<1;
    dword tile_offset = 0;  //changed to dword to store 32 bit address
    word map_offset = 0;
    word screen_offset = 0;
    asm{
        push ds
        push di
        push si

        mov     dx,12       //column

        lds     bx,[tiledata]                   
        lds     si,ds:[bx]              //ds:si data address
        mov     word ptr[tile_offset],ds //store a word
        mov     word ptr[tile_offset+2],si

        les     bx,[mapdata]
        mov     ax,es:[bx]
        mov     cl,8
        shl     ax,cl
        add     si,ax
        mov     di,screen_offset        //es:di screen address                          
    }
    loop_tile:
        asm{
        mov     ax,0A000h
        mov     es,ax
        mov     ax,16
    }
    copy_tile:  
    asm{
        mov     cx,8
        rep     movsw               
        add     di,320-16
        dec     ax
        jnz     copy_tile

        mov     ds,word ptr[tile_offset]  //read a word to the register
        mov     si,word ptr[tile_offset+2]

        mov     ax,map_offset
        add     ax,[width]        
        mov     map_offset,ax

        les     bx,[mapdata]
        add     bx,ax
        mov     ax,es:[bx]
        mov     cl,8
        shl     ax,cl
        add     si,ax

        dec     dx
        jnz     loop_tile

        pop si
        pop di
        pop ds
    }   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...