2016-01-27 42 views
0

我有一个程序,我可以这样调用:寻址指针数组中ASM

mov rdi, struc_point 
mov rsi, struc_color 
call put_pixel 

现在,我想创建类似指针数组有一个颜色表。我现在已经是这一点,它不工作:

color_table: 
dq 0 ; null color 
dq struc_color1 
dq struc_color2 
dq struc_color3 
; etc..., the colors are defined somewhere else 

现在,我愿做这样的事情与它到底:

mov rbx, 2 ; index into color table 
mov rdi, struc_point 
mov rsi, qword [color_table+8*rbx] 
call put_pixel 

到底哪里出问题了?没有编译器错误,但是当我运行它时,所有动画都会停止。 rsi应包含地址struc_color,请参阅第一个片段。如果我对这种颜色进行硬编码(mov rsi, struc_color),程序将起作用。

这是在x86_64 asm中,无需任何操作系统直接启动。

+0

当我运行这个,所有的动画停止。没有编译器错误。 'rsi'应该包含struc颜色的基地址,请参阅第一个片段。如果我对颜色进行硬编码(因此省略颜色表('mov rsi,sky_color')),程序就能正常工作 - 每个像素都以这种颜色正确显示。所以这个问题似乎与“颜色表”有关。 – poetryofruins

+0

而不是64位指针,为什么不直接在颜色表中存储颜色?或者,如果您指向的定义是连续存储的,则可以存储8位或16位索引。顺便说一下,'mov ebx,2'会保存一个指令字节(REX前缀),除非你的汇编程序在可能的时候已经离开它。 –

+0

使用该表的片段与不包含的片段不同。一:它打破了'rbx'。你在这个函数中保存/恢复'rbx'吗? (假设你正在使用一个调用约定,其中'rbx'是一个被调用者保存的寄存器。)“struc_color2”与“struc_color”相同吗?你有没有试过在bochs或其他x86模拟器/仿真器上运行你的自制系统,所以你可以从外面调试它?例如看看它卡在哪里? –

回答

0

我发现了这个问题。我上面写的代码实际上是正确的,并且运行良好。

该问题位于put_pixel之内,它不保存rax。而且我实际上只使用了rax,并将数据存储在其中。这导致put_pixel在第一次运行时抛弃该程序。

+1

如果您将一些寄存器指定为call-clobbered,那么您可能会发现代码变得更加高效,因此函数可以在不保存/恢复的情况下使用它们。我建议使用标准ABI之一,如SysV ABI(请参阅http://stackoverflow.com/tags/x86/info)。 Windows 64位调用约定通常更糟糕的IMO,但有一些向量寄存器调用保留是有趣的(Windows ABI指定了太多的向量寄存器作为保存的调用,尽管它们大多数可用作临时寄存器可能更好)。 –