检查两块瓷砖是否在NASM装配中接触并相邻

时间:2013-10-24 00:58:57

标签: algorithm assembly nasm

假设我有一个2D数组,我想检查一个插槽是否相邻并与另一个插槽接触。

假设坐标位于4字节变量中:OneXOneYTwoXTwoY

我有一段时间的解决方案是,如果你有差异OneX - OneYTwoX - TwoY并添加它们,如果结果是1-1,那么是的,插槽是相邻的并且接触。

mov EBX,[oneX]
sub EBX,[oneY]
mov ECX,[twoX]
sub ECX,[twoY]
add EBX,ECX
; Compare EBX with 1 or -1.......

这几乎可行。但是没有 - 给定格式(x,y),取:(3,3)和(0,1)。它们显然不相邻也不触及,但功能会说它们是。

Get adjacent elements in a two-dimensional array?的问题有点用处,但它侧重于查找所有相邻的匹配,而我想检查两个特定的插槽。

我的数组的结构是这样的:

map: dd 'a','b','c','d'  ; Double words just to make my life easier

这被解释为

a b
c d

这是一张方形图。

2 个答案:

答案 0 :(得分:1)

没有理由添加它们!你也减少了不正确的变量:)。

您必须有两个条件OneX - TwoXOneY - TwoY:两者都必须为1,0或-1。

例如,一个是[4,5],两个是[5,5]> = OneX - TwoX = -1OneY - TwoY = 0 =>它是相邻的瓷砖。

编辑:对于非对角线,有两种方法:

a)其中一个条件必须为0,另一个条件必须为1或-1

b)添加OneX - TwoX的绝对值和OneY - TwoY的绝对值必须为1

答案 1 :(得分:1)

这是一些基于@libik答案的实用代码:

针对速度进行了优化:

; eax = OneX-TwoX; ecx = OneY-TwoY
        mov    eax, [OneX]
        mov    ecx, [OneY]
        sub    eax, [TwoX]
        sub    ecx, [TwoY]

; eax = abs(eax); ecx=abs(ecx)
        mov    ebx, eax
        mov    edx, ecx
        sar    ebx, 31
        sar    edx, 31
        xor    eax, ebx
        xor    ecx, edx
        sub    eax, ebx
        sub    ecx, edx

; eax=abs(delta1)+abs(delta2); if eax = 1, jump to where needed
        add    eax, ecx
        dec    eax
        lz     .adjacent 

针对尺寸进行了优化:

; eax = abs(OneX-TwoX); ecx = abs(OneY-TwoY)
        mov    eax, [OneX]
        mov    ecx, [OneY]
        sub    eax, [TwoX]
        jns    @f
        neg    eax
@@:
        sub    ecx, [TwoY]
        jns    @f
        neg    ecx
@@:
; eax=abs(delta1)+abs(delta2); if eax = 1, jump to where needed
        add    eax, ecx
        dec    eax
        lz     .adjacent 

包括对角线案例

add eax, ecx替换为or eax, ecx