2014-02-13 42 views
0

我正在学习汇编,需要创建2个数组。对于第一个,我添加了2,然后打印这些值。第二个我减去2并打印。这些价值观是正确的。当我尝试交换值时,我会得到稍微偏离的数字值。我换换错了吗?交换汇编

.586 
.MODEL FLAT 

INCLUDE io.h   ; header file for input/output 

.STACK 4096 

.DATA 

array1 DWORD 21H,22H,23H,24H,25H 
array2 DWORD 31H,32H,33H,34H,35H 

resultLbl1 BYTE "Array 1 values are",0 
resultLbl2 BYTE "Array1 value1 is",0 
resultLbl3 BYTE "Array1 value2 is",0 
resultLbl4 BYTE "Array1 value3 is",0 
resultLbl5 BYTE "Array1 value4 is",0 
resultLbl6 BYTE "Array1 value5 is",0 
string1 BYTE 40 DUP (?) 
count DWORD 0 

.CODE 
_MainProc PROC 





     ;add 2 to array1 elements 

     mov eax, array1 
     add eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array1+4 
     add eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array1+8 
     add eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array1+12 
     add eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array1+16 
     add eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 


     ;subtract 2 from array2 elements 


     mov eax, array2 
     sub eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array2+4 
     sub eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array2+8 
     sub eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array2+12 
     sub eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 

     mov eax, array2+16 
     sub eax, 2 
     dtoa string1, eax 
     output resultLbl1, string1 


     ;Swap array values in reverse 


     mov eax, array2+16 
     xchg array1, eax 

     mov eax, array2+12 
     xchg array1+4, eax 

     mov eax, array2+8 
     xchg array1+8, eax 

     mov eax, array2+4 
     xchg array1+12, eax 

     mov eax, array2+4 
     xchg array1+12, eax 


     mov eax, array2 
     xchg array1+16, eax 

     mov eax, array1 
     dtoa string1, eax 

     output resultLbl2, string1 

     mov eax, array1+4 
     dtoa string1, eax 

     output resultLbl3, string1 


     mov  eax, 0 ; exit with return code 0 
     ret 
_MainProc ENDP 
END        ; end of source code 

回答

1

它看起来像你的xchg使用是错误的。首先是因为xchg只为eax写入该值才被下一条指令杀死,第二条因为xchg带有内存参数有一个(浪费的)隐式锁前缀。

你应该使用明确的临时变量来代替:

mov eax, array1 
mov edx, array2+16 
mov array2+16, eax 
mov array1, edx 

线条

mov eax, array2+4 
xchg array1+12, eax 

也被复制,这是可疑的。

+0

对于xchg的锁可能不会执行任何操作,除非正在使用支持多个共享内存总线的处理器的Xeon或其他服务器cpu。 – rcgldr

+0

命中并且没有足够快地编辑它。我的理解是,锁定握手逻辑已禁用或从英特尔台式机处理器中删除。英特尔台式机主板也不支持它。在台式机处理器和主板上使用xchg时,似乎不太可能有任何额外的“锁定”开销。 – rcgldr

+0

另一种情况是,锁由进程中的多个线程或多个共享内存的进程使用。假设这是一个单线程的进程,该锁不应该引起额外的开销。 – rcgldr

0

程序将array2的值移动到array1中,但需要第二个mov将array1的值移动到array2中。正如gsg所指出的那样,使用xchg比使用mov需要更多的时间,所以我更新了这段代码片段以使用mov。

mov  eax,array2+16 
    mov  edx,array1 
    mov  array1,eax 
    mov  array2+16,edx 
    mov  eax,array2+12 
    mov  edx,array1+4 
    mov  array1+4,eax 
    mov  array2+12,edx 
    mov  eax,array2+8 
    mov  edx,array1+8 
    mov  array1+8,eax 
    mov  array2+8,edx 
    mov  eax,array2+4 
    mov  edx,array1+12 
    mov  array1+12,eax 
    mov  array2+4,edx 
    mov  eax,array2 
    mov  edx,array1+16 
    mov  array1+16,eax 
    mov  array2,edx