我正在阅读这里的一些答案和问题,并不断提出这个建议,但我注意到没有人真正解释过你需要做什么,在Windows上使用英特尔和GCC编译器.下面评论正是我想要做的.
#include <stdio.h>
int main()
{
int x = 1;
int y = 2;
//assembly code begin
/*
push x into stack; < Need Help
x=y; < With This
pop stack into y; < Please
*/
//assembly code end
printf("x=%d,y=%d",x,y);
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
int bn_div(bn_t *bn1, bn_t *bn2, bn_t *bnr)
{
uint32 q, m; /* Division Result */
uint32 i; /* Loop Counter */
uint32 j; /* Loop Counter */
/* Check Input */
if (bn1 == NULL) return(EFAULT);
if (bn1->dat == NULL) return(EFAULT);
if (bn2 == NULL) return(EFAULT);
if (bn2->dat == NULL) return(EFAULT);
if (bnr == NULL) return(EFAULT);
if (bnr->dat == NULL) return(EFAULT);
#if defined(__i386__) || defined(__amd64__)
__asm__ (".intel_syntax noprefix");
__asm__ ("pushl %eax");
__asm__ ("pushl %edx");
__asm__ ("pushf");
__asm__ ("movl %eax, …Run Code Online (Sandbox Code Playgroud) 考虑以下汇编代码循环:
#include <iostream>
#define ADD_LOOP(i, n, v) \
asm volatile ( \
"movw %1, %%cx ;" \
"movq %2, %%rax ;" \
"movq $0, %%rbx ;" \
"for: ;" \
"addq %%rax, %%rbx ;" \
"decw %%cx ;" \
"jnz for ;" \
"movq %%rbx, %0 ;" \
: "=x"(v) \
: "n"(i), "x"(n) \
: "%cx", "%rax", "%rbx" \
);
int main() {
uint16_t iter(10000);
uint64_t num(5);
uint64_t val;
ADD_LOOP(iter, num, val)
std::cout << val << std::endl;
return 0; …Run Code Online (Sandbox Code Playgroud) 我需要这样的内联汇编代码:
像这样:
__asm__ __volatile__ ("push %%eax\n\t"
// ... some operations that use ECX as a temporary
"mov %0, %%ecx\n\t"
// ... some other operation
"pop %%eax"
: : "m"(foo));
// foo is my local variable, that is to say, on stack
Run Code Online (Sandbox Code Playgroud)
反汇编编译后的代码时,编译器给出的内存地址是0xc(%esp),它是相对于 的esp,因此,由于我push之前有一个操作,这段代码将无法正常工作mov。因此,我怎么能告诉编译器我不喜欢foo相对于esp,但像-8(%ebp)相对于 ebp 的任何东西。
PS 你可能会建议我可以放在eaxClobbers 里面,但这只是一个示例代码。我不想展示我不接受此解决方案的完整原因。
我已经开始在 GCC/G++ 下开发一个小型 16 位操作系统。我正在使用 GCC 交叉编译器,它是在 Cygwin 下编译的,我将 asm(".code16gcc\n") 作为每个 .CPP 文件的第一行,使用 Intel ASM 语法和命令行来编译和链接.CPP 文件如下所示:
G++: i586-elf-g++ -c $(CPP_FILE) -o $(OBJECT_OUTPUT) -nostdinc -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fpermissive -masm=intel
LD: i586-elf-ld -T $(LD_SCRIPT) $(OBJECT_OUTPUT) -o $(BINARY_OUTPUT)
Run Code Online (Sandbox Code Playgroud)
我目前面临的问题是GCC 将函数调用代码翻译成汇编的方式。
更具体地说,GCC 不使用 PUSH 指令来传递参数,而是“计算”参数相对于 ESP 的偏移量,然后使用 MOV 指令手动写入堆栈。
这对我来说没有好处,因为我依赖汇编代码中的 PUSH 指令。为了更清楚地说明我的问题,请使用以下两个函数:
void f2(int x);
void f1(){
int arg = 8;
asm("mov eax, 5"); // note: super hacky unsafe use of GNU C inline asm
asm("push eax"); // Writing registers without …Run Code Online (Sandbox Code Playgroud) 在过去的几天里,我一直在为一种试图获得 EFLAGS 状态的奇怪行为而苦苦挣扎。为此,我编写了以下代码:
#include <stdio.h>
int flags_state()
{
int flags = 0;
__asm__ __volatile__("pushfq");
__asm__ __volatile__("pop %%rax": "=a"(flags));
return flags;
}
int main()
{
printf("Returning EFLAGS state: 0x%x\n", flags_state());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当它运行时,我得到:
./flags
Returning EFLAGS state: 0x246
Run Code Online (Sandbox Code Playgroud)
当我打印两次标志时,它变得更奇怪了
Returning EFLAGS state: 0x246
Returning EFLAGS state: 0x206
Run Code Online (Sandbox Code Playgroud)
当我尝试打印 6 次时它发生了变化
Returning EFLAGS state: 0x246
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Run Code Online (Sandbox Code Playgroud)
最后是最奇怪的(至少对我来说),当我打印 8 次时
Returning EFLAGS state: …Run Code Online (Sandbox Code Playgroud)