Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Assembler] Сортировка последовательности чисел 
:(
    Опции темы
Pakshin A. S.
  Дата 4.3.2007, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



Цитата

С клавиатуры вводится последовательность целых восьмеричных чисел. Упорядочить по возрастанию (по убыванию).
Корректность вводимых данных должна проверяться. Числа могут быть отрицательными. Результат выводится в той же системе счисления. Преобразование строки в число и обратно оформить в виде процедур.


Вот такое задали задание...

Нашел похожее задание и его решение: http://forum.vingrad.ru/topic-124735.html
Как его переделать или лучше писать заново?

 smile 

PM   Вверх
anwe
Дата 4.3.2007, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 748
Регистрация: 2.9.2006

Репутация: 9
Всего: 23



Зачем же писать заново? Можно передалать на восьмиричную ввод и вывод. smile 
PM MAIL   Вверх
Pakshin A. S.
Дата 4.3.2007, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



 smile Хмм... А как?  smile 
PM   Вверх
anwe
Дата 4.3.2007, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 748
Регистрация: 2.9.2006

Репутация: 9
Всего: 23



По вводу (нажатию на ентер) проверять коды введеных символов (и не забывать про возможный первый минус smile )

Добавлено @ 23:30 
Не заметил твоё  smile 
Вот он:
Код

    xor    ax,ax
    mov    cl,len
    xor    ch,ch
    mov    si,cx
    xor    bx,bx
    mov    cl,10
l1:
    mov    bl,byte ptr z[di]
    sub    bl,'0'
    jb    lerror
    cmp    bl,9
    ja    lerror
    mul    cx
    add    ax,bx
    inc    di
    cmp    di,si
    jb    l1
    cmp    byte ptr z[0],'-'
    jne    l4
    neg    ax
l4:

PM MAIL   Вверх
Pakshin A. S.
  Дата 1.5.2007, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



Итак, вот что получилось:

Код

.386

.model flat, stdcall

option      casemap:none

include     windows.inc
include     kernel32.inc
include     user32.inc
includelib  kernel32.lib
includelib  user32.lib 

.data
    hStdOut   dd ?
    hStdIn    dd ?
    mes       db "Enter elements (separator - space): ",0Dh,0Ah
    kol_chars dd 1
    stroka    db 1 dup (?)
    massiv    dw 255 dup (?) 
    buf          db 100 dup (?)
    count1      db ?
  
.code
start:
    
    ;--------------
    ; получение идентификаторов ввода-вывода
    ;--------------
    push    STD_OUTPUT_HANDLE
    call    GetStdHandle         
    mov     hStdOut, eax

    push    STD_INPUT_HANDLE
    call    GetStdHandle         
    mov     hStdIn, eax
    
            
    ;;;--------------;;;
    ;;;   Поехали!   ;;;
    ;;;--------------;;;
    
    ;--------------
    ; Вывод приглашения ввода последовательности
    ;--------------
    push    0
    push    offset kol_chars
    push    sizeof mes          
    push    offset mes
    push    hStdOut
    call    WriteConsole         

    ;--------------
    ; Ввод последовательности
    ;--------------
    xor     esi, esi
    xor     ax, ax
    mov        count1, 0
    while1:
        push    0
        push    offset kol_chars
        push    1
        push    offset stroka
        push    hStdIn
        call    ReadConsole          
        
        cmp     stroka, 13
        je      sorting
        
        cmp     stroka, " "
        je      l1
            mul        ax
            mov     bl, stroka
            sub     bl, '0'
            add     ax, bx
            jmp     while1
        l1:
            mov     massiv[esi], ax
            xor     ax, ax
            inc        count1
            inc     esi
            jmp     while1   
    cmp        ax, 0
    je        sorting
    mov        massiv[esi], ax
    inc        count1
    ;--------------
    ; Сортировка
    ;--------------
    sorting:
    dec        count1
    movzx   ecx, count1        
    shr     ecx, 1        
    lea        ebx, massiv
    xor    esi, esi
    f1:
        xor    edi, esi
        f2: 
            mov    ax, massiv[esi]
            cmp    ax, massiv[edi]
            jl        c1
                mov    ax,massiv[esi]    
                xchg    massiv[edi],ax    
                mov    massiv[esi],ax            
            c1:
            inc    edi
            cmp    edi, ecx
            jb        f2
        inc    esi
        cmp    esi, ecx
        jb        f1
      
    ;--------------
    ; Пытаемся вывести массив на экран
    ;--------------
    xor        esi, esi
    l3:
        mov     ax,[ebx+esi*2]    
        push    ax
        xchg    ah,al
        call    print_all       ;вывод старшей цифры
        pop     ax
        call    print_all       ;вывод младшей цифры
        inc        esi        
        cmp        esi, ecx
        jb        l3
    print_all:
        mov        dh,al         ;сохраняем
        and     dh,0Fh         ;младшую цифру
        shr     al,4
        call    print_n         ;вывод старшей цифры
        mov     al,dh         ;восстанавливаем младшую и вывод
    print_n:
        cmp     al,10
        sbb     al,69h
        das
        push    0
        push    offset kol_chars
        push    10           ; сколько символов выводить
        push    ax
        push    hStdOut
        call    WriteConsole    ; вывод на консоль        
        ret
  
    ;;;--------------;;;
    ;;;  Приехали... ;;;
    ;;;--------------;;;
    
    ret
end start


Все бы хорошо, но вот только вылетает программа... И не пойму почему... :(

Добавлено через 1 минуту и 15 секунд
Сейчас прога берет рпосто числа в массив и выводит массив в шестнадцатиричной системе
PM   Вверх
anwe
Дата 5.5.2007, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 748
Регистрация: 2.9.2006

Репутация: 9
Всего: 23



Цитата

Все бы хорошо, но вот только вылетает программа... И не пойму почему... :(

Возможных причин тут две. В порядке вероятности влияния на вылет.
1) Рекомендуется заканчивать программу через ExitProcess с кодом выхода. У тебя же все заканчивается на строке ret, где выводятся значения. Смотри, вызывается print_all для вывода цифр. А после строки jb l3, когда условие уже не истинно, все равно идет на print_all. То есть и заканчивается на ret и выводит не известно что. Но это мало вероятно.
2) WriteConsole требует указателя на выводимую строку, у тебя же ax содержит значение. Его максимальное значени (даже теоретически) 65535. Значит обращается к этой, запрещенной ячейке памяти.
И еще. Винда работает так, что значение регистра edx после выполнения API-функций не сохраняется, что там возвращается - не известно. А ты его используешь для хранения выводимых цифр. Это на вылет, конечно, не влияет, просто выведешь не то, что надо.
Мне проще было сделать самому, нежели корректировать твою. Это несмотря на то, что я и сам не работал с консолью, но, разобравшись, понял, что ты не правильно с ней работал. Меня, наверное как и тебя, смутило это:
Цитата

function reads character input from the console input buffer and removes it from the buffer

Мол, читает по символам. Но это не так. Это character input from the console. Ведь второй параметр: address of buffer to receive data (что надо для строки), да и в отладчике увидел воочию - считывается вся строка.
Так что пришлось переделывать программу под работу и корректировку именно строки, а не как делал ты - считывал посимвольно.
И выводить по условиям твоего задания надо в той же системе счисления, а ты пытался выводить в 16-ричной. Кстати, у меня без запроса консоли у ОСи программа не пошла. Так что держи код.
Код

.386

.model flat, stdcall

option      casemap:none

include     windows.inc
include     kernel32.inc
include     user32.inc
includelib  kernel32.lib
includelib  user32.lib 

.data
hStdOut    dd    ?
hStdIn    dd    ?
mes    db    'Enter elements (separator - space): ',0Dh,0Ah
mes_error    db    'Error: the number ',1,' is not valid',0Dh,0Ah
kol_chars    db    255 dup(0)
mes_large    db    'Error: the number ',1,' is large',0Dh,0Ah
stroka    db    255 dup(0)
chislo    dd    255 dup(0)
vstroka    db    255 dup(0)
dlina    dd    ?
predel    db    0
posledniy    db    0
minus    db    0
kol_chisel    db    1
  
.code
start:
    
    ;--------------
    ; получение идентификаторов ввода-вывода
    ;--------------
    call    AllocConsole
    test    eax, eax   ; запрос консоли у ОС
    jz    ex
    push    STD_OUTPUT_HANDLE
    call    GetStdHandle         
    mov     hStdOut, eax

    push    STD_INPUT_HANDLE
    call    GetStdHandle         
    mov    hStdIn, eax
    
            
    ;;;--------------;;;
    ;;;   Поехали!   ;;;
    ;;;--------------;;;
    
    ;--------------
    ; Вывод приглашения ввода последовательности
    ;--------------


    push    0
    push    offset kol_chars
    push    sizeof mes          
    push    offset mes
    push    hStdOut
    call    WriteConsole  

     
    ;--------------
    ; Ввод последовательности
    ;--------------

    push    0
    push    offset kol_chars
    push    255
    push    offset stroka
    push    hStdIn
    call    ReadConsole

    push    ebx
    push    edi
    push    esi

    push    offset stroka
    call    lstrlen
    mov    byte ptr stroka[eax-2],20h
    cmp    byte ptr stroka[eax-3],20h
    jne    q4
    dec    eax
    q4:
    dec    eax
    mov    dlina,eax
    mov    ebp,offset stroka
    xor    esi,esi
    xor    edx,edx
    xor    ebx,ebx
    cld
q3:
    mov    ecx,dlina
    mov    edi,ebp
    mov    al,20h
    repne    scasb
    push    edi
    sub    edi,ebp
    pop    ebp
    push    edi
    sub    dlina,edi
    sub    edi,2
    js    q5
    cmp    edi,10
    ja    q_error
    jb    q9
    mov    predel,1
q9:
    mov    ecx,edi
    xor    eax,eax
q2:
    mov    bl,byte ptr stroka[edi][edx]
    test    edi,edi
    jnz    q1
    cmp    bl,2Dh
    jne    q7
    neg    eax
    jmp    q6
q7:
    cmp    predel,0
    je    q1
    mov    posledniy,1
q1:
    sub    bl,30h
    jb    q_error
    cmp    bl,7h
    ja    q_error
    cmp    posledniy,0
    je    q8
    cmp    bl,3
    ja    q_large
q8:
    push    ecx
    sub    ecx,edi
    imul    ecx,3
    shl    ebx,cl
    pop    ecx
    add    eax,ebx
    xor    ebx,ebx
    dec    edi
    jns    q2
q6:
    mov    dword ptr chislo[esi],eax
    add    esi,4
q10:
    pop    edi
    add    edx,edi
    mov    posledniy,0
    mov    predel,0
    inc    kol_chisel
q5:
    cmp    dlina,0
    jbe    vyvod
    jmp    q3


vyvod:
    mov    edi,esi
    sub    esi,4
    xor    esi,esi
    mov    edx,1
q12:
    xor    eax,eax
    mov    al,12
    mul    dl
    movzx    ebx,al
    mov    eax,dword ptr chislo[esi]
    test    eax,eax
    jns    q13
    neg    eax
    mov    minus,1
q13:
    mov    ecx,12
q11:
    mov    byte ptr vstroka[ebx],al
    and    byte ptr vstroka[ebx],111b
    or    byte ptr vstroka[ebx],30h
    shr    eax,3
    dec    ebx
    loop    q11
    cmp    minus,0
    je    q14
    mov    byte ptr vstroka[ebx+1],2Dh
q14:
    add    esi,4
    mov    minus,0
    inc    edx
    sub    edi,4
    jnz    q12
    mov    edi,offset vstroka
    inc    edi
    mov    ecx,255
    xor    al,al
    repne    scasb
    sub    edi,offset vstroka
    sub    edi,1
    push    0
    push    offset kol_chars
    push    edi
    push    offset vstroka
    push    hStdOut
    call    WriteConsole

push    MB_OK
push    0
push    offset vstroka+1
push    0
call    MessageBox

    pop    esi
    pop    edi
    pop    ebx
ex:
    push    0   
    call    ExitProcess
q_error:
    mov    al,kol_chisel
    or    al,30h
    mov    byte ptr mes_error[18],al
    push    edx
    push    0
    push    offset kol_chars
    push    sizeof mes_error
    push    offset mes_error
    push    hStdOut
    call    WriteConsole
    pop    edx

push    MB_OK
push    0
push    offset mes_error
push    0
call    MessageBox

    cmp    kol_chisel,1
    je    ex
    jmp    q10

q_large:
    mov    al,kol_chisel
    or    al,30h
    mov    byte ptr mes_large[18],al
    push    edx
    push    0
    push    offset kol_chars
    push    sizeof mes_large
    push    offset mes_large
    push    hStdOut
    call    WriteConsole
    pop    edx

push    MB_OK
push    0
push    offset mes_large
push    0
call    MessageBox

    cmp    kol_chisel,1
    je    ex

    jmp    q10
end start

Вот такое вот получилось. smile 
MessageBox ввел специально, чтобы виден был результат в консоле. Иначе она закрывается сразу и ничего не успеваешь увидеть.
И вообще, я не понимаю почему надо работать именно с консолью!  smile Для окна можно было хотя бы переопределить оконную процедуру - уже полегче.
PM MAIL   Вверх
Pakshin A. S.
Дата 5.5.2007, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



Огромное спасибо! Буду сидеть разбираться...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0518 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.