https://wandbox.org/permlink/fNyh3Nj0LroooFFq
#include <cstring>
#include <iostream>
using namespace std;
char *doSmth(char *s)
{
volatile register char *p asm("rax") = s;
__asm__
("\
.intel_syntax noprefix \n\
inc rax \n\
inc byte ptr [rax] \n\
");
return (char*)p;
}
int main()
{
char s[] = "abcXYZ";
cout << s << ' ' << doSmth(s) << endl;
return 0;
}
Выводится
abcXYZ accXYZ
т. е. инкремент символа происходит верно, а инкремент указателя тоже как бы происходит (изменён верный символ), но только внутри ассемблерной вставки и не отражается на переменной, используемой в дальнейшем коде.
А хотелось бы получить строку с ожидаемо отрезанным первым символом:
abcXYZ ccXYZ
Как исправить?
Компилятор же не знает, что вы там внутри переменную p поменяли, и берёт значение не из регистра, а из переменной s (её-то вы не меняли, а там записано то же самое). Это один из вариантов, на самом деле их до чёрта. Такая ситуация называется UB (undefined behavior).
Чтобы компилятор не занимался самодеятельностью, надо рассказать ему какие переменные изменялись. Например, так:
char *doSmth(char *s)
{
__asm__ volatile (
"inc %0\n"
"incb (%0)\n"
: "+r"(s) : : "memory");
return s;
}
Здесь "+r" (s)
означает, что переменная s должна быть доступна для чтения и записи как регистр, а volatile и "memory"
означают, что в процессе могли измениться посторонние данные (т.е. не являющиеся ни входными параметрами, ни выходными).
Подробнее о синтаксисе можно прочитать здесь: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
У меня результат зависит от включённой оптимизации.
Работает, как предполагалось, при
--- testold.cpp 2019-10-30 12:25:49.539828727 +0100
+++ test.cpp 2019-10-30 12:24:11.419439287 +0100
@@ -9,7 +9,6 @@
__asm__
("\
- .intel_syntax noprefix \n\
inc rax \n\
");
и компиляции с g++ -masm=intel test.cpp
. Если не указывать -masm=intel, то не ассемблируется. Если собирать с -O1
или выше, то переменная не изменяется.
user@host:~/path$ ./a.out
1234567 234567
user@host:~/path$
Debian, amd64, g++ 6.3.0
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Плохо разбираюсь в семантике JS, помогите,пожалуйстаБраузер ругается на лишние символы в данных скриптах