首页 > 解决方案 > 汇编变量被删除(16 位 x86 汇编)

问题描述

我仍在使用用于 MS-DOS 的 turbo C 进行复古编程,我发现使用变量有些麻烦。

如果我在汇编代码的开头(在 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)替换它,代码就会按预期工作(这使用地图数组绘制一列图块,一些图块存储在ram中) .

我想这与推送/弹出等有关,并且没有按应有的设置。

纯汇编中会发生什么?没有一个变量起作用。我将它们定义为 DW 并添加了:

push bp
mov bp,sp

;function 

mov sp,bp
pop bp

谢谢。

标签: variablesassemblyx86

解决方案


好吧再次感谢,下次我会在询问之前更加耐心。

以防万一这对某人有用,我使用错误的大小定义了一个变量。还有其他可以改进的地方,但这是另一个问题。

变量“tileoffset”保存一个 32 位地址,因此它必须是“dword”,而不是“word”。那么函数应该是这样的:

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
    }   

推荐阅读