Робята подмогите как реализовать сдвиг влево для того чтобы удалить символ из цепочки символов. У меня TASM
Грубо говоря можно так (удалить четверку): Код (Text): string db '123456789',0 size = $-string mov esi,string mov edi,string mov ecx,4-1 repnz movsb mov ecx,size-4 inc esi repnz movsb
Если неизвестно, то никто не мешает найти месторасположение четверки и вставить в код вместо 4 новую позицию
Можно и не искать её месторасположение, просто пропустить когда встретится: Код (Text): .data string db '123456789',0 .code lea ebx,string _loop1: cmp byte ptr[ebx],'4' je _loop2 cmp byte ptr[ebx],0 je _fin inc ebx jmp _loop1 _loop2: inc ebx mov al,byte ptr[ebx] mov byte ptr[ebx-1],al test al,al jnz _loop2 _fin: PrintString string
Извините, но у меня возник вопрос, а что означает 0 в следующей записи: string db '123456789',0. Большое спасибо
Не обращай внимания или считай его тоже символом, я по привычке добавил ноль как признак окончания строки, в том коде он не нужен (его роль выполняет переменная size), у cresta наоборот вместо переменной используется ноль (обычно это выгоднее)
А если строчка символов находится в буфере. Ведь из этого же буфера выводить исправленную строчку нельзя, а тогда нужно использовать movs как тогда правильно задавать cx (количество передаваемых байтов)
ego Ты бы уточнил задачку: 1) какие у тебя строки - с замыкающим нулем или а-ля ShortString Pascal или еще какие ? 2) какой символ тебе нужно удалять - по заданному номеру (индексу) от начала строки или его еще нужно найти (например найти и удалить пробел или все пробелы в строке) ? 3) нужно изменить саму исходную строку или создать ее измененную копию ?
Память под результат надо выделять? Если нет тогда примерно так: (esi - адрес исходной строки, edi - адрес результата, al - удаляемый символ для ascii-z строк: Код (Text): mloop: mov ah, byte ptr[esi] inc esi cmp ah, al je skip mov byte ptr[edi], ah inc edi skip: or ah, ah jne mloop для pascal-строк: Код (Text): xor ecx, ecx mov cl, byte ptr[esi] mov ebx, ecx inc esi push edi inc edi mloop: mov ah, byte ptr[esi] inc esi cmp ah, al je skip mov byte ptr[edi], ah inc edi loop mloop skip: dec ebx loop mloop pop edi mov byte ptr[edi], bl
Ustus Кстати к вопросу об оптимизации: без особой необходимости не следует смешивать в одной операции младший и старший 8-битовые регистры, т.к. это требует дополнительного внутреннего мопа на сдвиг старшего байта. Так что если регистров хватает лучше использовать младшие байты разных регистров
Согласен, просто написать за пять минут проще, чем оптимизировать за час да и прога вроде не для Пентагона ) и loop лучше заменить на dec\je(для Intel'а по крайней мере, AMD по-моему пофиг) М-м-м... чего-то я не нахожу такой пакости... это для всех процов?
Ustus > "loop лучше заменить на dec\je" Правильно, только лучше не на dec, а на sub ecx,1 т.к. dec имеет ложную и совершенно ненужную зависимость по флагу CF от предыдущих операций, а времена экономии пары байтов медленно, но верно уходят в прошлое > "AMD по-моему пофиг" Тебе пофиг, а AMD нет Открываем AMD Optimization Guide и видим, что loop это VectorPath с латентностью 8 тиков 8((, а dec+je от силы 2 > "это для всех процов?" Ес-но, т.к. регистра ah в природе не существует, впрочем как и al - в 32-разрядных процах есть только eax (хотя на самом деле и его нет, но это уже другой вопрос )) > "написать за пять минут проще, чем оптимизировать за час" Это точно, но к родному языку, впитанному с молоком матери, это не относится ) Я например для себя не задумываясь пишу sub ecx,1 вместо dec ecx, но когда нужно запостить чего на форум старательно исправляю чтобы не вызывать лишних дискусий у любителей экономить байты А всякие там loop - это вообще ненормативная лексика и произносить такое даже язык не поворачивается, тем более писать ) PS: надеюсь, ты на смайлики внимание обращаешь и не воспринимаешь мои заметки близко к сердцу ))
leo Согласен, но: Скорее экономлю текстовое пространство Ну почему же, это хорошо, когда есть кому потыкать носом в заблуждения Как ничто другое способствует их искоренению.