2014-12-23 7 views
0

Я пробовал читать об этом по всему Интернету, но вот это моя проблема. Мне дается строка двойных слов.x86 Asm Insertion sort

Я должен заказать в порядке убывания строку нижних слов (наименее значимых) из этих двойных слов. Высокие слова остаются неизменными. Для примера: strin DD 12345678h 1256ABCDh, 12AB4344h результатом будет 1234ABCDh, 12565678h, 12AB4344h.

Теперь я попытался изо всех сил направить некоторый код, но он не работает должным образом, моя процедура вставки. Если бы вы могли взглянуть и сказать мне, что я делаю неправильно, я был бы великодушен. Я попытался запустить его в режиме td, но я просто не могу понять.

assume cs:code, ds:data 
data segment 
    s dd 12345678h, 1256ABCDh, 12AB4344h 
    ls equ ($-s)/4 ;this is supposed to be the length of my source string 
    d dd ls dup (?) ;this is my destination string 
    aux dw ? 
    aux2 dw ? 
data ends 

code segment 
insert proc 
    push di ;here I use the stack to get more free registers 
    push cx 
    cmp di, offset d ;if di=offset d it means that I didn't store any number yet 
    je addPrim 
    std ;we plan on working form right to left on the string for the next part 
    mov cx, di 
    sub cx, offset d ;here I find out with how many words I have to compare the word from AX 
    dec di 
    dec di ;since I work with doublewords, for some reason I thought I should decrease di 
    dec di ;3 times but here my procedure gets fuzzy and doesn't work properly anymore 
    repeta1: ;this repeat is supposed to compare the word from AX with the rest of the least 
     scasw ;significant words from es:di 
     jge DIplus2 ;if my number from AX is bigger or equal than what's in es:di, I increment 
;di twice and store it 
     mov bx, word ptr es:[di+1] ;this part is supposed to interchange words but it's not 
;working how I planned so I don't know how to change it 
     mov word ptr es:[di+2], bx 
     loop repeta1 

    jmp DIplus1 

    DIplus2: 
     inc di 

    DIplus1: 
     inc di 

    addPrim: ;this label just adds the first word in the destination string 
     stosw 

    pop cx 
    pop di 
    inc di 
    inc di 
    cld 
    ret 
    insert endp 

start: 
    mov ax, data 
    mov ds, ax 
    mov es, ax 
    mov si, offset s 
    mov di, offset d 
    mov cx, ls ; store in cx the length of the strings 
    jcxz exit 

repeta: 
    lodsw ;because of little endian, my first word will be my least significant word in the 
;in the doubleword so right after it is moved in ax, i apply the procedure insert 
    call insert 
    lodsw ;here it moves in ax my most significan word in the dd, so i auto store it 
    stosw ;in my destination string 
    loop repeta 

exit: 
    mov ax, 4c00h 
    int 21h 

code ends 
end start 

ответ

0
ls equ ($-s)/4 ;this is supposed to be the length of my source string 

Это фактически вычисляет количество элементов.

mov cx, di 
sub cx, offset d ;here I find out with how many words ... 

На втором вызове вашей вставки прок это установит CX = 4, который является слишком большим, учитывая список только 3 значения. Я предлагаю вам разделить CX на 4.

dec di 
dec di ;since I work with doublewords... 
dec di ;3 times but here my procedure gets fuzzy 

Это, безусловно, неправильно. SCASW указывает, что вы либо уменьшаетесь на 4, либо не уменьшаетесь вообще!

mov bx, word ptr es:[di+1] ;this part is supposed to interchange words... 
mov word ptr es:[di+2], bx 

Это не может работать, так как смещения всего лишь 1 байт!

jmp DIplus1 

Это дает однократное увеличение DI и, следовательно, ошибку, потому что вы хотите сохранить слово в этом месте.

+0

Ооо спасибо! Я исправил его, и теперь он работает правильно. Я раньше работал с scasw, но я изменил его на cmp, а затем DI-шаги больше не нужны. Большое спасибо. – Katie44

Смежные вопросы