Значит проблема такая: Есть код на С++, вот он: Код (Text): #include <stdio.h> #define N 20000 //алгоритм "решето Эратосфена" unsigned int a[N]; void main(){ //заполним все ячейки числами по порядку: 0,1,2,3... for(int i=0; i<N; i++){ a[i] = i; } //поскольку 1 не простое число, обнулим ячейку с этим числом a[1]=0; for(int s=2; s<N; s++){ if(a[s]!=0){ for(int j=s*2; j<N; j+=s){ a[j]=0; } } } for(i=0; i<N; i++){ if(a[i]!=0){ printf("%d\n", a[i]); } } } Это код нахождения простых чисел методом решета Эратосфена. Я (строго не судите, студент, ничего не знаю) написал код на масме, но наделал кучу косяков. Собственно код вот: Код (Text): .386 .model flat, stdcall option casemap:none include \9-II-SKS\myasm\include\windows.inc include \9-II-SKS\myasm\include\kernel32.inc include \9-II-SKS\myasm\include\user32.inc includelib \9-II-SKS\myasm\lib\user32.lib includelib \9-II-SKS\myasm\lib\kernel32.lib BSIZE equ 100 BSZZ equ 15 .data stdout DWORD ? cWritten DWORD ? nn DWORD ? digit DWORD ? mn DWORD ? per DWORD ? Massive DWORD BSIZE dup (?) ifmt BYTE "%d",0 buf BYTE BSIZE dup (?) crlf BYTE 0dh, 0ah .code start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov stdout, eax mov ecx, BSIZE mov ebx,0 mov edi,0 nxt: mov Massive[edi], ebx inc ebx add edi,4 loop nxt mov Massive [1],0 mov edi,0 nxt1: inc edi mov edx, Massive[edi] mov digit, edx cmp edi, BSIZE jnz nxt3 cmp digit,0 jnz nxt1 mov nn,edi mov eax,2 mul edi nxt2: mov Massive[eax],0 add eax,nn cmp eax,BSIZE ja nxt1 jnz nxt2 nxt3: mov edi, 0 mov eax,0 nxt4: mov edx, Massive[edi] mov per, edx add edi,4 cmp per,0 jnz nxt4 mov eax, Massive[edi] invoke wsprintf,ADDR buf,ADDR ifmt,eax invoke WriteConsoleA,stdout,ADDR buf,BSZZ,ADDR cWritten,NULL cmp edi,BSIZE jnz nxt4 jnz exit exit: invoke ExitProcess,0 end start Короче говоря мозги кипели, и наделал всякой чуши Кто есть знающий подскажите на косяки, и помогите доделать плз. ПРОШУ строго не судите это моя почти первая прога на ассемблере
спасибо за прогу, но мне хотелось бы разобратся что не так в моей. услышать подсказки и дополнения. ну и что можно переделать, тока с обьяснениями, чтоб я понял
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 ... * По моему мнению
А чего подсказывать. Чужую прогу на ассемблере тяжело "прокручивать". Придется компилить и отлаживать. Но это же самое можешь сделать и ты. И пользы будет гораздо больше.
Во первых в начале программы вызовем консоль 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, чтоб увидеть что у тебя получилось. Остальные свои ошибки найдешь сам.