Помогите разобратся masm

Тема в разделе "WASM.ASSEMBLER", создана пользователем Dj_Maestro, 13 янв 2010.

  1. Dj_Maestro

    Dj_Maestro New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2010
    Сообщения:
    4
    Значит проблема такая:
    Есть код на С++, вот он:
    Код (Text):
    1. #include <stdio.h>
    2.     #define N 20000
    3.     //алгоритм "решето Эратосфена"
    4.     unsigned int a[N];
    5.     void main(){
    6.        //заполним все ячейки числами по порядку: 0,1,2,3...
    7.        for(int i=0; i<N; i++){
    8.            a[i] = i;
    9.        }
    10.        //поскольку 1 не простое число, обнулим ячейку с этим числом
    11.        a[1]=0;
    12.        for(int s=2; s<N; s++){
    13.            if(a[s]!=0){
    14.                for(int j=s*2; j<N; j+=s){
    15.                    a[j]=0;
    16.                }
    17.            }
    18.        }
    19.        for(i=0; i<N; i++){
    20.            if(a[i]!=0){
    21.                 printf("%d\n", a[i]);
    22.            }
    23.        }
    24.     }
    Это код нахождения простых чисел методом решета Эратосфена.
    Я (строго не судите, студент, ничего не знаю) написал код на масме, но наделал кучу косяков.
    Собственно код вот:
    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap:none
    4. include \9-II-SKS\myasm\include\windows.inc
    5. include \9-II-SKS\myasm\include\kernel32.inc
    6. include \9-II-SKS\myasm\include\user32.inc
    7. includelib \9-II-SKS\myasm\lib\user32.lib
    8. includelib \9-II-SKS\myasm\lib\kernel32.lib
    9. BSIZE equ 100
    10. BSZZ equ 15
    11. .data
    12. stdout DWORD ?
    13. cWritten DWORD ?
    14. nn DWORD ?
    15. digit DWORD ?
    16. mn DWORD ?
    17. per DWORD ?
    18. Massive DWORD BSIZE dup (?)
    19. ifmt BYTE "%d",0
    20. buf BYTE BSIZE dup (?)
    21. crlf BYTE 0dh, 0ah
    22. .code
    23. start:
    24. invoke GetStdHandle,STD_OUTPUT_HANDLE
    25. mov stdout, eax
    26. mov ecx, BSIZE
    27. mov ebx,0
    28. mov edi,0
    29. nxt:
    30. mov Massive[edi], ebx
    31. inc ebx
    32. add edi,4
    33. loop nxt
    34. mov Massive [1],0
    35. mov edi,0
    36. nxt1:
    37. inc edi
    38. mov edx, Massive[edi]
    39. mov digit, edx
    40. cmp edi, BSIZE
    41. jnz nxt3
    42. cmp digit,0
    43. jnz nxt1
    44. mov nn,edi
    45. mov eax,2
    46. mul edi
    47. nxt2:
    48. mov Massive[eax],0
    49. add eax,nn
    50. cmp eax,BSIZE
    51. ja nxt1
    52. jnz nxt2
    53. nxt3:
    54. mov edi, 0
    55. mov eax,0
    56. nxt4:
    57. mov edx, Massive[edi]
    58. mov per, edx
    59. add edi,4
    60. cmp per,0
    61. jnz nxt4
    62. mov eax, Massive[edi]
    63. invoke wsprintf,ADDR buf,ADDR ifmt,eax
    64. invoke WriteConsoleA,stdout,ADDR buf,BSZZ,ADDR cWritten,NULL
    65. cmp edi,BSIZE
    66. jnz nxt4
    67. jnz exit
    68. exit:
    69. invoke ExitProcess,0
    70. end start
    Короче говоря мозги кипели, и наделал всякой чуши:dntknw:

    Кто есть знающий подскажите на косяки, и помогите доделать плз. ПРОШУ строго не судите это моя почти первая прога на ассемблере:)
     
  2. al79

    al79 Алексей

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    133
    Адрес:
    Екатеринбург
    Вот что получилось у меня на скорую руку:
     
  3. Dj_Maestro

    Dj_Maestro New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2010
    Сообщения:
    4
    спасибо за прогу, но мне хотелось бы разобратся что не так в моей. услышать подсказки и дополнения. ну и что можно переделать, тока с обьяснениями, чтоб я понял
     
  4. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    Dj_Maestro

    Если стоит задача переписывания C->ASM или наоборот, то сначала следует* стараццо перебивать один-в-один не взирая на то, что "а на конечном языке можно сделать и вот так" и уже после отладки "базового" варианта писать улучшения.

    ; #define N 20000
    ; Так и пишем, ТЕ ЖЕ имена!!
    N equ 20000
    ; //алгоритм "решето Эратосфена"
    ; Обычно есть три метода выделения памяти - неинициализированная в приложении (как ты сделал), stack and VirtualAlloc,
    ; ok, lets use .data?
    ; unsigned int a[N];
    .data?
    a dd N dup(?)
    .code
    ; void main(){
    ; //заполним все ячейки числами по порядку: 0,1,2,3...
    ;
    ; for(int i=0; i<N; i++){
    xor ebx,ebx
    @@FillArray:
    ; a = i;
    ; }
    ... ну пусть будет как у тебя, неважно ...

    ...
    mov Massive [1],0 ; Тут может быть ошибко - нужно проверить что компиллер верно сделал +4

    ; for(int s=2; s<N; s++){
    mov ...
    ; Так и пишем с отступами как в C.
    ; if(a!=0){
    cmp ...

    * По моему мнению
     
  5. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    А чего подсказывать. Чужую прогу на ассемблере тяжело "прокручивать". Придется компилить и отлаживать. Но это же самое можешь сделать и ты. И пользы будет гораздо больше.
     
  6. al79

    al79 Алексей

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    133
    Адрес:
    Екатеринбург
    Во первых в начале программы вызовем консоль invoke AllocConsole
    Потом сам вывод информации, замени
    cmp per,0
    jnz nxt4
    на
    cmp per,0
    jz nxt4 - а то у тебя получается нужно выводить только "0"

    Затем, у тебя задано количество чисел, и это ты сравниваешь с edi хотя edi увеличиваешь на 4, надо хотябы сделать так cmp edi,4*BSIZE-4
    И переменные поправь наверно в конце надо так:
    buf db BSZZ-2 dup (0)
    crlf BYTE 0dh, 0ah,0

    Да и перед выходом сделай хотябы invoke MessageBoxA,0,0,0,0, чтоб увидеть что у тебя получилось.
    Остальные свои ошибки найдешь сам.