问题
I was given a task to convert a certain code from C++ to ASM based on AT&T syntax, so I started with simple examples and encountered the first problem.
code from which I started the exercise
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
num = num << 3;
std::cout << "after: " << num << std::endl;
}
which gives a result:
before: 1
after: 8
my translation variable num is first local variable so it should be in address -4(%ebp)
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
asm (
"mov -4(%ebp), %eax \n"
"sall $3, %eax \n"
"mov %eax, -4(%ebp) \n"
);
std::cout << "after: " << num << std::endl;
}
which gives a result:
before: 1
after: 1
why this code has no effect on num var ?
回答1:
The code you are writing is very implementation specific. In your case the code likely doesn't work because you are using ebp
which is a 32-bit addressing register, while you are running on a 64-bit machine, which uses rbp
.
HOWEVER you are approaching this incorrectly. Either you write pure assembly, or you use the correct (extended) C inline assembly, that correctly interfaces with local variables. Else the code will break as soon as you change something, as you have experienced yourself.
according to this answer the inline asm should look like:
asm ( "assembly code"
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
so your code could look like
asm (
"mov %0, %%eax;"
"sal $3, %%eax;"
"mov %%eax, %1;"
:"=r" (num)
:"r" (num)
:"%eax"
);
However, you don't need to specify and use eax
, thus the code could be simplified (and clarified) to
asm (
"sal $3, %[num];"
:[num] "+r" (num)
);
来源:https://stackoverflow.com/questions/65346574/the-code-after-conversion-does-not-execute-a-given-action