нужно помочь найти ошибку

Тема в разделе "WASM.BEGINNERS", создана пользователем giskar, 23 авг 2007.

  1. giskar

    giskar New Member

    Публикаций:
    0
    Регистрация:
    2 авг 2007
    Сообщения:
    43
    Товарищи, ниже представлен код с ошибкой. Помогите пожалуста исправить. Две строчки с ошибками выделены и закоментированы. Не понимаю, почему не выполняется MOVZX, или, что тоже самое, word ptr wax+2,mas[4]. Как вы поняли, я хочу запихнуть слово mas[4], в младшую часть двойного слова wax. Имеют ли смысл мои попытки? в чём ошибка? Обратите внимание, что без этих двух строчек на экран выводится один массив(как мне кажется верный), но если например вставить в кок строчку MUL WAX, то на экран выведится уже другой массив( как мне кажется НЕ верный). Почему так?

    Код (Text):
    1. .model small
    2.  
    3. .586
    4.  
    5. .stack 100h
    6.  
    7. .data
    8. mes db "po umolchaniu dick C: $",0ah,0dh
    9. mas dw 4 dup(?)
    10. mus db 0Ah,0Dh,0Ah,'$'
    11.        
    12.  
    13. .data?
    14. wax dd ?
    15. way dd ?
    16. len dw ?
    17.  
    18. .code
    19.  
    20. ;вывод строки на экран
    21. sc proc
    22.      mov ah,9
    23.      int 21h
    24.  
    25.      ret
    26. sc endp
    27.  
    28. ;вывод числа из ax на экран
    29. num proc    
    30.                                                              ; AX - число   ES:DI-куда писать ответ
    31.                 std                                       ; Запись справа налево для STOSB
    32.          
    33.                 push ax
    34.  
    35.                 mov al,'$'
    36.                 stosb
    37.  
    38.                 pop ax              
    39.  
    40.                 mov     bx,10                      ; Делитель
    41. diving:
    42.                 xor     dx,dx                         ; Чтобы избежать переполнения при делении
    43.                 div     bx                               ; AX=частное DX=остаток
    44.                                                              ; DX=DL % 10
    45.                 push    ax
    46.                 mov     ax,dx
    47.  
    48.                 add     al,'0'
    49.                 stosb                                    ; AX -> [ES:DI] ; DEC DI
    50.  
    51.                 pop     ax
    52.                 or      ax,ax                          ; Частное было равно нулю?
    53.                 jnz     diving                         ; Нет-продолжить цикл
    54.  
    55.                 push ds
    56.                 push es
    57.                 pop ds
    58.  
    59.                 mov dx,di
    60.                 mov ah,9
    61.                 int 21h
    62.  
    63.                 pop ds
    64.                              
    65.                 ret
    66. num endp
    67.  
    68.  
    69. main:
    70. mov ax,@data
    71. mov ds,ax
    72.  
    73.  
    74. mov ah,19h              ;получаем номер заданного
    75. int 21h                      ; по умолчанию дисковода
    76. jc exit
    77.  
    78. cmp al,02                                                    ; 02 - "C:\"
    79. ;jne pul
    80. mov dl,al
    81.  
    82. mov dx,offset mes
    83. call sc
    84.  
    85. mov ah,36h           ;получаем инфу о свободном дисковом
    86. int 21h                   ; пространстве
    87.  
    88.  
    89.                
    90.                ; ax - число секторов в одном кластере
    91.                ; bx - количество свободных кластеров
    92.                ; cx - размер сектора в байтах
    93.                ; dx - общее число кластеров на диске
    94.  
    95.  
    96. mov esi,0
    97. mov mas[0],ax
    98. mov mas[2],bx
    99. mov mas[4],cx
    100. mov mas[8],dx
    101.  
    102.      xor ax,ax    
    103.       mov ax,mas[0]
    104.      call num                       ;выводим число секторов
    105.      
    106.       xor ax,ax        
    107.       mov ax,mas[2]
    108.       call num                    ;свободных кластеров
    109.      
    110.  
    111.      xor ax,ax    
    112.      mov ax,mas[4]
    113.      call num                    ; размер сектора в байтах
    114.  
    115.      xor ax,ax      
    116.       mov ax,mas[8]
    117.      call num                   ; и общее число кластеров
    118.  
    119.  
    120. ;считаем свободное пространство на диске :  ax*bx*cx    
    121.  
    122. xor ax,ax
    123. mov ax,mas[0]
    124.      
    125. mul mas[2]                              
    126.  
    127. mov word ptr wax,dx
    128. mov word ptr wax+2,ax                  
    129.                                                          ;теперь в wax находится ax*bx
    130.  
    131. xor ax,ax
    132. xor dx,dx
    133. mov eax,wax                                 ;теперь в eax находится ax*bx
    134.  
    135. mov wax,0
    136.  
    137. ;MOVZX WAX,MAS[4]                ;в wax находится cx ?
    138.  
    139. ;MUL WAX                               ;умножаем cx на ax*bx ?
    140.  
    141.  
    142. exit:
    143.      mov ah,10h
    144.      int 16h
    145.  
    146.      mov ax,4c00h
    147.      int 21h
    148.      
    149. end main
     
  2. nobodyzzz

    nobodyzzz New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2005
    Сообщения:
    475
    x86 не поддерживает операцию пересылки из памяти в память
     
  3. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    1) используйте регистр, mov не может писать из памяти в память только через регистр
    2)как он ругается на строку "MUL WAX"? с размерностью не напутали?
    3)
    cx, ecx в процессе выполнения команды mul не используется
     
  4. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    movs?
     
  5. giskar

    giskar New Member

    Публикаций:
    0
    Регистрация:
    2 авг 2007
    Сообщения:
    43
    Ага, всё исправил.Спасибо.

    А не подскажите как при выполнении программы перейти на другую строку в командной строке, ну т.е. у меня, как видите в программе выводится строка "po umolchaniu dick C:", а затем сразу после неё выводятся элементы массива mas, а я хочу, что бы элементы массива выводились уже на другой строчке. Не подскажите как это сделать?
     
  6. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    MultiString db "line1", 0dh, 0ah, "line2"
    вообще-то управляющие символы расписаны в любом мало-мальском учебнике по ассемблеру
     
  7. giskar

    giskar New Member

    Публикаций:
    0
    Регистрация:
    2 авг 2007
    Сообщения:
    43
    rain
    Спасибо. У меня их 4, ни в одном не нашёл:)))
     
  8. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Найди старые, но мощные доки вроде TechHelp!, HelpPC, Журдена и прочие хорошие книжки. Их в инете много.
     
  9. giskar

    giskar New Member

    Публикаций:
    0
    Регистрация:
    2 авг 2007
    Сообщения:
    43
    почему то асм не сравнивает 64-разрядную переменную quotent типа qword с нулём:

    cmp quotent,0
    jnz io

    На это он выдаёт ошибку A2070. Объясните в чём моя ошибка?
     
  10. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    на х86 нету 64битных регистров и соответственно таких возможностей сравнивай по частям либо через cmps, ну или купи новый камень и программируй в родном для него режиме :)
     
  11. giskar

    giskar New Member

    Публикаций:
    0
    Регистрация:
    2 авг 2007
    Сообщения:
    43
    Посмотрите пожалуста код. Прога должна вывести в десятиричном виде число divident. Собственно она это похоже и делает(жаль не могу проверить - в калькуляторе только 9-ть цифр), но с глюками: число почемут выводится несколько раз, с какими-то буковками, и прога зависает. Вобщем сассемблируйте и посмотрите пожалуста что не так. Вот код с коментариями:
    Код (Text):
    1. .model small
    2.  
    3. .586
    4.  
    5. .stack 100h
    6.  
    7. .data
    8. divident qword 0FFFFFFFFFFFFFFFFh
    9. quotent qword ?
    10. modulo dw ?
    11. ha dword 00000000h
    12.  
    13. .code
    14. num2 proc  
    15.                 std                           ;
    16.                push ax                      ; для вывода строки
    17.                mov al,'$'                    ; на экран    
    18.                stosb                         ;
    19.                pop ax                        ;    
    20.          
    21.                mov     bx,10               ; делим на 10
    22.  
    23.                                                                            ;начинаем делить
    24.               xor ax,ax
    25.               mov        ax,word ptr divident+6
    26.              xor        dx,dx
    27.              div        bx
    28.              mov        word ptr quotent+6,ax
    29.  
    30.              xor ax,ax
    31.               mov        ax,word ptr divident+4
    32.              div       bx
    33.              mov        word ptr quotent+4,ax
    34.  
    35.               xor ax,ax
    36.              mov        ax,word ptr divident+2
    37.             div        bx
    38.             mov        word ptr quotent+2,ax
    39.  
    40.             xor ax,ax
    41.             mov        ax,word ptr divident
    42.              div        bx
    43.              mov        word ptr quotent,ax
    44.  
    45.             mov        modulo,dx
    46.  
    47.                                                                 ; теперь остаток в modulo
    48.                                                                 ; а частное в quotent
    49. io:
    50.          
    51.         ;    mov eax,dword ptr quotent+8           ; сохраняем частное    
    52.         ;     mov edx,dword ptr quotent  
    53.                
    54.                 push ax                                       ;
    55.                                                                  ;
    56.               xor ax,ax                                       ; выводим первую часть
    57.                                                                  ;  нашего числа
    58.               mov ax,modulo                                ; (и далее последущие см. ниже)
    59.                                                                   ;
    60.                 add     al,'0'                                  ;                  
    61.                                                                   ;
    62.                 stosb                                           ;
    63.                                                                   ;
    64.                 pop    ax                                      ;
    65.  
    66.        ;      mov dword ptr quotent+8,eax            
    67.        ;      mov dword ptr quotent,edx            
    68.  
    69.               push eax                                         ;  начинаем проверять quotent
    70.                                                                    ; на равенство нулю по частям
    71.               xor eax,eax                                      ;
    72.                                                                    ;
    73.              mov eax,dword ptr quotent                  ; первая часть:
    74.              cmp eax,ha                                       ; Частное было равно нулю?
    75.              jnz    diving                                       ; не равно
    76.                                                                    ;
    77.              xor eax,eax                                       ;
    78.                                                                    ;
    79.              mov eax,dword ptr quotent+8               ; вторая часть:
    80.              cmp eax,ha                                       ; Частное было равно нулю?
    81.              jnz    diving                                       ; не равно
    82.  
    83.              jmp up
    84.                
    85. diving:                                                          ;quotent не был равен нулю - делим дальше
    86.               pop eax
    87.  
    88.                xor ax,ax
    89.                mov     ax,word ptr quotent+6    
    90.                xor dx,dx                                            
    91.                 div bx                                                
    92.                mov    word ptr quotent+6,ax  
    93.  
    94.              xor ax,ax
    95.                mov        ax,word ptr quotent+4
    96.                 div        bx
    97.                mov        word ptr quotent+4,ax
    98.  
    99.                xor ax,ax
    100.                 mov        ax,word ptr quotent+2
    101.                 div        bx
    102.                mov        word ptr quotent+2,ax
    103.  
    104.                 xor ax,ax
    105.                 mov        ax,word ptr quotent
    106.                 div        bx
    107.                mov        word ptr quotent,ax
    108.  
    109.                 mov        modulo,dx
    110.                                                                 ; теперь остаток в modulo
    111.                                                                 ; а частное в quotent
    112.                 jmp io
    113.  
    114. up:                                             ; выводим строку из es:di на экран
    115.                                                  
    116.                 push ds
    117.                 push es
    118.                 pop ds
    119.  
    120.                mov dx,di
    121.                 mov ah,9
    122.                 int 21h
    123.  
    124.                 pop ds
    125.                              
    126.                 ret
    127. num2 endp
    128.  
    129.  
    130. main:
    131. mov ax,@data
    132. mov ds,ax
    133.  
    134. call num2
    135.  
    136. mov ah,10h
    137. int 16h
    138.  
    139. mov ax,4c00h
    140. int 21h
    141.  
    142. end main
     
  12. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Код (Text):
    1. mov eax,dword ptr quotent+8               ; вторая часть:
    Почему 'quotent+8'? Должно быть 'mov eax,dword ptr quotent + 4'. Ну и по-мелочи:

    1. Очищать регистр перед использованием не нужно. Т.е. в
    Код (Text):
    1. xor eax,eax                                      ;
    2. mov eax,dword ptr quotent                  ; первая часть:
    'xor eax, eax' не нужен.

    2. Переменная 'ha' тоже не нужна -- команда cmp умеет работать с непосредственными операндами, т.е. можно заменить на 'cmp eax, 0x0'.

    3. Стек будет несбалансированным, при при выходе по 'jmp up' -- тогда у инструкции 'push eax' не будет пары 'pop xxx'. От этого можно избавиться, заменив
    Код (Text):
    1.              mov eax,dword ptr quotent                  ; первая часть:
    2.              cmp eax,ha                                       ; Частное было равно нулю?
    3.              jnz    diving
    на
    Код (Text):
    1.              cmp dword ptr quotent,0x0                                       ; Частное было равно нулю?
    А вообще, это что новый способ деления больших чисел? :)
     
  13. giskar

    giskar New Member

    Публикаций:
    0
    Регистрация:
    2 авг 2007
    Сообщения:
    43
    Mika0x65
    Ага, спасибо, всё исправил, всё работает)) А вобще, это я 64-разрядное число на экран просто хочу уметь выводить:)) Я не знаю, может быть существует способ и покороче, кроме как делить это число на 10 всё время:)) Ну можно ещё сдвигами, но я в них чё т не разобрался:))
     
  14. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Сдвиги - не что иное, как деление на число, равное степени двойки (2, 4, 8, 16...), используются при выводе чисел в системе счисления с основанием, равным степени двойки. 10 - это не степень двойки, поэтому на сдвиг прямо не заменяется.