LINUX.ORG.RU

инкрементировать string


0

0

Вопрос очень простой.
Нужно инкрементировать string не используя встроенные функции.
вот код на С++:

string A=«asd»,B;
cout<<A;
for(int i=0;i<3;i++)
{
B[2-i]=A[i];
}
cout<<B;
Знаю он не правильный. Подскажите как лучше это сделать.
заранее огромное спасибо!

Вот, блин, любители всё усложнять!

#include <string>
#include <iostream>
//-------------------------------------------------------------------
int main(int argc,char** argv)
{
 std::string A("0123456789");
 std::string B;
 std::string::reverse_iterator rit;
 for(rit=A.rbegin();rit != A.rend();++rit)
 { B+=*rit; }
 std::cout<<"A="<<A<<", B="<<B<<std::endl;
 return 0;
}
one_more_hokum ★★★
()
Ответ на: комментарий от qnikst
#!/bin/sh 
echo $* | rev 

это можно вызвать из c через fork() и exec

Это точно лучшее решение в треде!

gizzka ★★
()
Ответ на: комментарий от yoghurt

> P.S. Попробуйте реверснуть фразу «Улыбок тебе дед Мокар»

У вас в первом классе уже закончились уроки?

andreyu ★★★★★
()
Ответ на: комментарий от anonymous

На каком?
Вообще говоря, в тех ассемблерах, которые для Symbolics Ivory или MIT CADR, может и были мнемоники, реализующие Z-комбинатор, но в существовании таких для того же x86 я сильно сомневаюсь.

Love5an
()

Нормальный алгоритм Маркова для слов из алфавита {A, B} ;)

1. βα → ^

2. αAA → AαA
3. αBB → BαB
4. αAB → BαA
5. αBA → AαB

6. αA → βA
7. αB → βB
8. αAβ → βγA
9. αBβ → βγB

10. γAA → AγA
11. γBB → BγB
12. γAB → BγA
13. γBA → AγB
14. γA → A
15. γB → B

16. A → αA
17. B → αB

Kristi
()
Ответ на: комментарий от anonymous

На асме слабО?

Если не использовать стандартные средства:

#include <iostream>

int main(int argc, char** argv) 
{

    asm ("decl %%edi\n"
         "jz l4\n"
         "movl %%esi,%%edi\n"
         "cld\n"
         "l1: lodsb\n"
         "testb %%al,%%al\n"
         "jz l2\n"
         "pushl %%eax\n"
         "jmp l1\n"
         "l2: subl %%edi,%%esi\n"
         "decl %%esi\n"
         "jz l4\n"
         "movl %%esi,%%ecx\n"
         "l3: popl %%eax\n"
         "stosb\n"
         "loop l3\n"
         "l4:\n"
         :
         : "D" (argc), "S" (argv[1])
         : "%ecx"
        );

        std::cout << argv[1] << std::endl;

        return 0; 
}
imhotep
()
Ответ на: комментарий от imhotep

Фигасе у тебя расход стека будет!

mv ★★★★★
()
Ответ на: комментарий от imhotep
#include <stdio.h>

void foo(char *str)
{
	asm volatile (
		"mov %%rdi, %%rsi\n"
		"xor %%al, %%al\n"
		"mov $-1, %%ecx\n"
		"repne scasb\n"
		"mov %%rdi, %%rcx\n"
		"sub $2, %%rdi\n"
		"sub %%rsi, %%rcx\n"
		"sar $1, %%rcx\n"
		"jz l2\n"
		"l1: mov (%%rsi), %%al\n"
		"xchg %%al, (%%rdi)\n"
		"mov %%al, (%%rsi)\n"
		"inc %%rsi\n"
		"dec %%rdi\n"
		"loop l1\n"
		"l2:\n"
		:
		: "D"(str)
		: "memory", "%rsi", "%rcx"
		);
}

int main()
{
	char f00[32] = { "foo bar baz" };
	foo(f00);
	printf("%s\n", f00);
	return 0;
}
mv ★★★★★
()
Ответ на: комментарий от mv

Неэфективно и ненеправильно. По большому счету это генератор случайных чисел с сегфолтами :) ибо никто не гарантирует что флаг df=0.

 
#include <stdio.h> 

void foo(char *str) 
{ 
   asm volatile ( 
      "movl %%edi,%%esi\n" 
      "xorb %%al,%%al\n" 
      "movl $-1,%%ecx\n" 
      "cld\n"
      "repne scasb\n" 
      "notl %%ecx\n"
      "decl %%ecx\n"
      "sarl $1,%%ecx\n" 
      "jz l2\n" 
      "subl $2,%%edi\n" 
      "std\n"
      "l1: movb (%%edi),%%al\n" 
      "xchgb %%al, (%%esi)\n" 
      "stosb\n"
      "incl %%esi\n" 
      "loop l1\n" 
      "l2:\n" 
      : 
      : "D"(str) 
      : "memory", "%ecx" 
      ); 
} 
 
int main() 
{ 
   char f00[32] = { "123456789" }; 
   foo(f00); 
   printf("%s\n", f00); 
   return 0; 
} 

imhotep
()
Ответ на: комментарий от imhotep

> ибо никто не гарантирует что флаг df=0.

ABI ядра гарантирует.

mv ★★★★★
()
Ответ на: комментарий от anonymous

> А по человечески без сишного компилера слабО? Или память распределять не умеем?

Деточка, мы, лисперы, всемогущи.

mv ★★★★★
()
Ответ на: комментарий от anonymous

Не надо сравнивать проганье и задротство.

Назови 10 отличий.

wfrr ★★☆
()
Ответ на: комментарий от mv

Почему же неэффективно и неправильно?

Как более эффективно сделать я поправил, а неправильно - я уже написал - никто не гарантирует что df=0, при чем тут abi какого-то ядра вообще непонятно ибо это чистый userspace и к ядру не имеет никакого отношения. Слови-ка сегфолт на своем коде :)

 
#include <stdio.h> 

void oof(void)
{
   asm("std");
}
 
void foo(char *str) 
{ 
   asm volatile ( 
      "mov %%edi, %%esi\n" 
      "xor %%al, %%al\n" 
      "mov $-1, %%ecx\n" 
      "repne scasb\n" 
      "mov %%edi, %%ecx\n" 
      "sub $2, %%edi\n" 
      "sub %%esi, %%ecx\n" 
      "sar $1, %%ecx\n" 
      "jz l2\n" 
      "l1: mov (%%esi), %%al\n" 
      "xchg %%al, (%%edi)\n" 
      "mov %%al, (%%esi)\n" 
      "inc %%esi\n" 
      "dec %%edi\n" 
      "loop l1\n" 
      "l2:\n" 
      : 
      : "D"(str) 
      : "memory", "%esi", "%ecx" 
      ); 
} 
 
int main() 
{ 
   char f00[32] = { "foo bar baz" }; 
   printf("мне в редхате сказали что abi ядра мне гарантирует безопасность\n");
   oof();   
   foo(f00); 
   printf("%s\n", f00); 
   return 0; 
} 

imhotep
()
Функция ПеревернутьСтроку(ВходнаяСтрока)
	Если СтрДлина(ВходнаяСтрока) = 0 Тогда
		Возврат "";
	ИначеЕсли СтрДлина(ВходнаяСтрока) = 1 Тогда
		Возврат ВходнаяСтрока;
	КонецЕсли;
	Попытка
		ДлинаСтроки = СтрДлина(ВходнаяСтрока);
		к = ДлинаСтроки - 1;
		Пока к > 0 Цикл
			ПеревернутаяСтрока = ПеревернутаяСтрока + ВходнаяСтрока[к];
			к = к - 1;
		КонецЦикла
	Исключение
		Сообщить("Программа выполнила недопустимую операцию");
	КонецПопытки
	Возврат ПеревернутаяСтрока;
КонецФункции
unsigned ★★★★
()
Ответ на: комментарий от imhotep

> asm(«std»);

Что уж там, давай сразу дереференс нулевого пойнтера.

mv ★★★★★
()
Ответ на: комментарий от imhotep

> Как более эффективно сделать я поправил,

Да брось, твой второй код принципиально ничем от моего не отличается. Мой от твоего - да первоначального.

mv ★★★★★
()
Ответ на: комментарий от mv

Что уж там, давай сразу дереференс нулевого пойнтера.

Это обычный флаг процессора - не надо передергивать - он может быть изменен где угодно и кем угодно.

# cat str.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define NR 100000

void foo(char *str) 
{ 
   asm volatile ( 
      "mov %%edi, %%esi\n" 
      "xor %%al, %%al\n" 
      "mov $-1, %%ecx\n" 
      "repne scasb\n" 
      "mov %%edi, %%ecx\n" 
      "sub $2, %%edi\n" 
      "sub %%esi, %%ecx\n" 
      "sar $1, %%ecx\n" 
      "jz l2\n" 
      "l1: mov (%%esi), %%al\n" 
      "xchg %%al, (%%edi)\n" 
      "mov %%al, (%%esi)\n" 
      "inc %%esi\n" 
      "dec %%edi\n" 
      "loop l1\n" 
      "l2:\n" 
      : 
      : "D"(str) 
      : "memory", "%esi", "%ecx" 
      ); 
} 

void my(char *str) 
{ 
   asm volatile ( 
      "movl %%edi,%%esi\n" 
      "xorb %%al,%%al\n" 
      "movl $-1,%%ecx\n" 
      "cld\n"
      "repne scasb\n" 
      "notl %%ecx\n"
      "decl %%ecx\n"
      "sarl $1,%%ecx\n" 
      "jz l4\n" 
      "subl $2,%%edi\n" 
      "std\n"
      "l3: movb (%%edi),%%al\n" 
      "xchgb %%al, (%%esi)\n" 
      "stosb\n"
      "loop l3\n" 
      "l4:\n" 
      : 
      : "D"(str) 
      : "memory", "%ecx" 
      ); 
} 

void my1(char *str) 
{ 
    asm ("movl %%esi,%%edi\n"
         "cld\n"
         "l11: lodsb\n"
         "testb %%al,%%al\n"
         "jz l12\n"
         "pushl %%eax\n"
         "jmp l11\n"
         "l12: subl %%edi,%%esi\n"
         "decl %%esi\n"
         "jz l14\n"
         "movl %%esi,%%ecx\n"
         "l13: popl %%eax\n"
         "stosb\n"
         "loop l13\n"
         "l14:\n"
         :
         : "S" (str)
         : "memory", "%ecx"
        );
}


int main() 
{ 
	int i;
	char *str = (char *)calloc(NR, 1); 

	if(str)
		memset(str, 1, NR-1);
	else
		return 0;

    time_t t1 = time(NULL);
	for(i = 0; i < 10000; i++)
	    foo(str);

	time_t t2 = time(NULL);
	for(i = 0; i < 10000; i++)
	    my(str);

	time_t t3 = time(NULL);
	for(i = 0; i < 10000; i++)
	    my1(str);

	time_t t4 = time(NULL);

	printf("foo: %d\nmy: %d\nmy1: %d\n", t2-t1, t3-t2, t4-t3);
	
	return 0; 
} 


# gcc str.c && ./a.out
foo: 18
my: 18
my1: 13
Как видишь мой первоначальный вариант при кажущейся неэфективности при работе со стеком работает заметно шустрее :)

imhotep
()
Ответ на: комментарий от imhotep

>Это обычный флаг процессора - не надо передергивать - он может быть изменен где угодно и кем угодно.

Надо же. А я наивно думал, что прерывания сохраняют состояние процессора :)

KRoN73 ★★★★★
()
Ответ на: комментарий от imhotep

> Это обычный флаг процессора - не надо передергивать - он может быть изменен где угодно и кем угодно.

Может. Но в том примере тебе для этого пришлось df явно руками менять.

Как видишь мой первоначальный вариант при кажущейся неэфективности при работе со стеком работает заметно шустрее :)


Эффективность выражается в потреблении ресурсов. Память - тоже ресурс. Причём, обычно более дорогой, чем такты.

mv ★★★★★
()
Ответ на: комментарий от KRoN73

>А я наивно думал, что прерывания сохраняют состояние процессора

Вы прерывания в юзерспейсе обрабатываете ? что за ОС ? наверно еще и на php обработчики пишете ?

imhotep
()
Ответ на: комментарий от imhotep

>Вы прерывания в юзерспейсе обрабатываете ?

При чём тут юзерспейс? Кто может поменять флаг изолированного процесса?

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>При чём тут юзерспейс?
При том что речь идет о пользовательских приложениях

Кто может поменять флаг изолированного процесса?

Сам процесс. Это не очевидно ? Банальный пример - вызов сторонней библиотеки. Смотри пример выше. Этим флагом (df) может оперировать любой код.

imhotep
()
Ответ на: комментарий от imhotep

>Сам процесс. Это не очевидно ?

Нет, не очевидно.

Банальный пример - вызов сторонней библиотеки


Если я _перед_ копированием выставлю флаг (а что, кто-то делает иначе?), и в процессе копирования сторонних библиотек вызывать не буду - кто мне поменяет флаг?

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Если я _перед_ копированием выставлю флаг (а что, кто-то делает иначе?)

mv это расскажи - он надеется на abi принятый в ос, что флаг будет иметь именно то значение которое ему нужно, я как раз не надеюсь и _сам_ указываю направление перед применением строковых команд, об этом и речь - научись наконец читать.

imhotep
()
Ответ на: комментарий от imhotep

>я как раз не надеюсь и _сам_ указываю направление перед применением строковых команд

Ну, извини, не всем нужна помощь К.О. в таких вопросах :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Вдогонку для сомневающимся в нужности этого :) http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2008-1367

Overview

gcc 4.3.x does not generate a cld instruction while compiling functions used for string manipulation such as memcpy and memmove on x86 and i386, which can prevent the direction flag (DF) from being reset in violation of ABI conventions and cause data to be copied in the wrong direction during signal handling in the Linux kernel, which might allow context-dependent attackers to trigger memory corruption. NOTE: this issue was originally reported for CPU consumption in SBCL.

imhotep
()
Ответ на: комментарий от imhotep

Этот секьюрити баг как раз опровергает твои предположения об обязательной установке df. Ядро меняло df, хотя не должно было, и в один момент времени это вылезло на поверхность. Если какая-то библиотека меняет флаг и потом не возвращает значение обратно, то программа сломается на первой же строчной функции.

mv ★★★★★
()
Ответ на: комментарий от mv

>баг как раз опровергает твои предположения об обязательной установке df

При этом твой код тормозит и валится а мой нет :) То что обнаружился баг в ядре при переходе с 4.2 на 4.3 в которой перестали принудительно сбрасывть флаг не значит что все баги найдены во всей куче написанного за многие годы.

imhotep
()
Ответ на: комментарий от KRoN73

> Ну, извини, не всем нужна помощь К.О. в таких вопросах :)

Читавшие «System V Application Binary Interface»*, а именно «AMD64 Architecture Processor Supplement», помнят, что на странице 15 в разделе «Function Calling Sequence», подраздел «Registers and the Stack Frame» написано: «The direction flag in the %eflags register must be clear on function entry, and on function return.» Для Intel386 то же самое.

Мне помощь К.О. в вопросах обязательной установки df в направлении forward не нужна, как не нужна и сама установка.

[*] http://refspecs.freestandards.org/

mv ★★★★★
()
Ответ на: комментарий от imhotep

> При этом твой код тормозит и валится а мой нет :)

Люди делятся на два типа: тех, кто читает спецификации, и тех, кто не читает.

То что обнаружился баг в ядре при переходе с 4.2 на 4.3 в которой перестали принудительно сбрасывть флаг не значит что все баги найдены во всей куче написанного за многие годы.


Я вообще сторонник идеологии fail fast*. Если баги есть, они должны быть найдены и исправлены, а не замаскированы.

[*] http://en.wikipedia.org/wiki/Fail-fast

mv ★★★★★
()
Ответ на: комментарий от mv

>Если баги есть, они должны быть найдены и исправлены, а не замаскированы.

Имхо это недостаток архитектуры х86 как и возможность исполнения стека так что хоть заправься - кому нужно все равно завалят твой код, я же просто сололмки подложил :)

imhotep
()
Ответ на: комментарий от mv

>Читавшие «System V Application Binary Interface»*, а именно «AMD64 Architecture Processor Supplement»

Какая жалость, что наверняка далеко не все разработчики сей документ читали.

Мне помощь К.О. в вопросах обязательной установки df в направлении forward не нужна, как не нужна и сама установка.


Правила тут были выработаны задолго до «System V Application Binary Interface».

KRoN73 ★★★★★
()
Ответ на: комментарий от imhotep

>Имхо это недостаток архитектуры х86 как и возможность исполнения стека

Пардон, но разве на 386+ не стало возможным запрещать исполнять код в сегменте стека? То, что во flat-модели сегмент стек совпадает с сегментом кода - это недостаток программной модели, а не архитектуры процессора.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Пардон, но разве на 386+ не стало возможным запрещать исполнять код в сегменте стека?

Мануал по Hardened Gentoo утверждает что с флагом NX не работают такие безусловно важные программы как XOrg. А у MS не работает ATL, т.к. трамплины для переключения из C API в ООП и обратно создаются на лету в куче.

Absurd ★★★
()
Ответ на: комментарий от KRoN73

Какая жалость, что наверняка далеко не все разработчики сей документ читали.

Большинство разработчиков не умеют работать со строками и плохо разбираются в школьной арифметике, судя по количеству и характеру багов. Всех расстрелять.

Правила тут были выработаны задолго до «System V Application Binary Interface».

Ну и сидите себе там с тамошними правилами ;) В Линуксе нужно соблюдать линуксовое ABI.

mv ★★★★★
()

а поподробней насчет df можно? если я его поставлю неправильно, а потом запущу что-нить суидное, типа ping, то оно упадет?

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Absurd

>Мануал по Hardened Gentoo утверждает что с флагом NX не работают такие безусловно важные программы как XOrg

Вот я и повторюсь, что процессор тут не при чём :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>>Мануал по Hardened Gentoo утверждает что с флагом NX не работают такие безусловно важные программы как XOrg

Вот я и повторюсь, что процессор тут не при чём :)

Флаг NX появился поздно, в ~P4. В ином случае он наверняка принимался бы в расчет.

Absurd ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.