2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Ассемблер. Массивы
Сообщение31.05.2018, 07:57 
Здравствуйте! Написал такой код(ассемблерная вставка), но в нем что-то не так. Что неверно?
Дан массив А из 16 байтов. Последовательно разбить его на слова. Если в слове старший байт не превышает
Младший(числа беззнаковые) заменить его нулем, предварительно скопиров в массив В
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
__asm
        {
                lea esi, A;
                lea edi, B;
               
        BEG:
             mov ah, [esi]; // al=a[i]
             cbw; //преобразовываем байт в слово
             inc esi; // увеличиваем на 1 (2 элемент)
             mov al, [esi]; //bl=a[2]
             inc esi; //3 элемент
             mov dl, [esi];
             sub dl, ah; // bl=a[i+1]-a[i-1]
             cmp bl, 0;
             JNE L; //если больше нуля
             mov bl, [esi];
             mov[esi], 0;
}

 
 
 
 Re: Ассемблер. Массивы
Сообщение31.05.2018, 09:53 
alexrr в сообщении #1316412 писал(а):
mov ah, [esi]; // al=a[i]

Содержание команды не вполне соответствует комментарию.

К тому же последующая команда cbw фактически сводит на нет результат её выполнения.

 
 
 
 Re: Ассемблер. Массивы
Сообщение31.05.2018, 12:04 
alexrr в сообщении #1316412 писал(а):
mov[esi], 0;

Компилятор на такое не ругается? Какому размеру операнда соответствует эта команда? Если байту, то надо написать что-то вроде
Код:
mov byte ptr [esi], 0;

 
 
 
 Re: Ассемблер. Массивы
Сообщение31.05.2018, 14:17 
alexrr
Вы бы хоть ошибки исправили, на которые компилятор ругается. И с записью нуля, и с меткой перехода.
В команде
Код:
sub dl, ah; // bl=a[i+1]-a[i-1]
регистр назначения указан неверно.
Записи в массив B вообще нигде нет.
Почему то у Вас цикл обрабатывает сразу 3 элемента массива, хотя сказано разбить на слова (вероятно по два байта).

Ну и так далее, здесь почти все команды неправильные (не нужны или делают не то что нужно). Тут не ошибки исправлять надо, а писать код заново строго по заданию с разбитием кода на осмысленные кусочки (прочитать, сравнить, записать если надо, зациклить) и с пониманием работы каждого шага. У Вас ни одно из этого не реализовано правильно (или хотя бы в работающем виде).

 
 
 
 Re: Ассемблер. Массивы
Сообщение06.06.2018, 15:30 
Dmitriy40 в сообщении #1316492 писал(а):
alexrr
Вы бы хоть ошибки исправили, на которые компилятор ругается. И с записью нуля, и с меткой перехода.
В команде
Код:
sub dl, ah; // bl=a[i+1]-a[i-1]
регистр назначения указан неверно.
Записи в массив B вообще нигде нет.
Почему то у Вас цикл обрабатывает сразу 3 элемента массива, хотя сказано разбить на слова (вероятно по два байта).

Ну и так далее, здесь почти все команды неправильные (не нужны или делают не то что нужно). Тут не ошибки исправлять надо, а писать код заново строго по заданию с разбитием кода на осмысленные кусочки (прочитать, сравнить, записать если надо, зациклить) и с пониманием работы каждого шага. У Вас ни одно из этого не реализовано правильно (или хотя бы в работающем виде).

Исправил. Есть продолжение условия задачи. Но выдает ошибку -1. Что ж тут не так?
код: [ скачать ] [ спрятать ]
Используется синтаксис C
//дан массив А из 16 байтов. Последовательно разбить его на слова. Если в слове старший байт не превышает
//младший(числа беззнаковые) заменить его нулем, предварительно скопиров в массив В, в массив С
// поместить адрес(смещение) этого слова. Сосчитать количесвто таких слов.
#include <stdio.h>
#include <stdafx.h>
int main() {
char B[5];
char* C[5];
int i = 0;
int Count = 0;
char A[5] = { 1,2,3,4,5 };
printf("Array A: \n");
for (i = 0; i<5; i++)
{
printf("%d", A[i]);
}
__asm
{
    lea esi, A;
    lea edi, B;
    lea ebx, C;
    mov cx, 5;
  BEG:

     mov al, [esi];
     mov ah, [edi];
     cmp ah, al;
     ja M; // Если в слове старший байт превышает младший(числа беззнаковые)
     L INACE;
     INACE:
     mov ah, 0;
     inc Count;
     mov [edi], ah;
     mov [ebx], edi;
     inc ebx;
  M:
     inc esi;
     inc edi;
     loop BEG;
}
  printf("Array B:\n");
  for (i = 0;i<Count;i++)
  printf("%d\n", B[i]);
  printf("Array C:\n");
  for (i = 0; i<Count; i++)
  printf("%p\n", C[i]);
  return 0;



}
 

 
 
 
 Re: Ассемблер. Массивы
Сообщение06.06.2018, 16:29 
alexrr
По условию вам дан массив из 16-ти байтов, у вас же в программе из 5-ти. Конечно это не критично, но 5 на слова не делится, в отличии от 16-ти ...
Далее, вы первыми двумя командами в цикле читаете два разных массива и потом их сравниваете. Но разве это надо делать по условию?! Нет! Надо прочитать два байта из массива А и именно их сравнивать.
После сравнения вы пишете в ah ноль, а ведь просили сначала скопировать его в массив B. Нету.
Да и ноль пишете в массив B, хотя ноль по условию надо писать в массив A.
В массив C пишете регистр edi (что кстати тоже неправильно), а на сколько увеличиваете указатель, а? Это не С с его типизированными указателями, тут о длине операндов надо думать самому.

Итого, впечатление что вы вообще не понимаете что делаете и допускаете банальные ляпы.
Может Вам легче будет записать сначала весь алгоритм на С и лишь потом покомандно перевести его на ассемблер (ровно как компилятор)?

PS. Почему выдаёт ошибку -1 я не знаю. Может какие регистры нельзя портить в асм коде (я всегда в таких случаях ставлю связку pushad/popad), может ещё что, без асм вставки программа отрабатывает нормально.

-- 06.06.2018, 16:36 --

А, возможно ошибку выдаёт из-за выхода за пределы массивов, ведь в старшей половине регистра ECX не обязательно ноль и цикл выполняется не обязательно 5 раз.
Выкладывать снова код с такими банальными опечатками - если это именно всего лишь опечатки, как и с регистром edi - ну не знаю, я бы постеснялся.

-- 06.06.2018, 16:38 --

Откройте для себя существование отладчика, пройдите под ним ваш цикл хотя бы первый раз обращая внимание на содержимое регистров - большинство указанных ошибок вылезут.

 
 
 [ Сообщений: 6 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group