相关疑难解决方法(0)

内核堆栈和用户空间堆栈

内核堆栈和用户堆栈之间有什么区别?为什么要使用内核堆栈?如果在ISR中声明了局部变量,那么它将被存储在哪里?每个进程都有自己的内核堆栈吗?然后这两个堆栈之间的进程如何协调?

linux linux-device-driver linux-kernel

94
推荐指数
3
解决办法
5万
查看次数

X86程序集 - 处理IDIV指令

我目前正在编写一个简单的C编译器,它将.c文件作为输入并生成汇编代码(X86,AT&T语法).一切都很好,但是当我尝试执行IDIVQ指令时,我得到一个浮点异常.这是我的意见:

int mymain(int x){
  int d;
  int e;
  d = 3;
  e = 6 / d;
  return e;
}
Run Code Online (Sandbox Code Playgroud)

这是我生成的代码:

mymain:
.LFB1:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movq    %rdi, -40(%rbp)
    movq    $3, -8(%rbp)
    movq    $6, %rax
    movq    -8(%rbp), %rdx
    movq    %rdx, %rbx
    idivq   %rbx
    movq    %rax, -16(%rbp)
    movq    -16(%rbp), %rax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1:
    .size mymain, .-mymain
Run Code Online (Sandbox Code Playgroud)

http://www.cs.virginia.edu/~evans/cs216/guides/x86.html,idivq%RBX应该产生在6/d(商)%RAX.但我得到一个浮点异常,我似乎无法找到问题.

任何帮助都感激不尽!

c compiler-construction x86 assembly

23
推荐指数
2
解决办法
2万
查看次数

为什么内核代码不能使用Red Zone

强烈建议在创建64位内核(对于x86_64平台)时,指示编译器不要使用用户空间ABI所执行的128字节红区.(对于GCC,编译器标志是-mno-red-zone).

如果启用了内核,则内核不会是中断安全的.

但那是为什么呢?

x86-64 abi red-zone

18
推荐指数
3
解决办法
2874
查看次数

为什么x86-64 GCC函数序言分配的堆栈少于局部变量?

考虑以下简单程序:

int main(int argc, char **argv)
{
        char buffer[256];

        buffer[0] = 0x41;
        buffer[128] = 0x41;
        buffer[255] = 0x41;

        return 0;
}
Run Code Online (Sandbox Code Playgroud)

在x86-64机器上使用GCC 4.7.0编译.用GDB反汇编main()给出:

0x00000000004004cc <+0>:     push   rbp
0x00000000004004cd <+1>:     mov    rbp,rsp
0x00000000004004d0 <+4>:     sub    rsp,0x98
0x00000000004004d7 <+11>:    mov    DWORD PTR [rbp-0x104],edi
0x00000000004004dd <+17>:    mov    QWORD PTR [rbp-0x110],rsi
0x00000000004004e4 <+24>:    mov    BYTE PTR [rbp-0x100],0x41
0x00000000004004eb <+31>:    mov    BYTE PTR [rbp-0x80],0x41
0x00000000004004ef <+35>:    mov    BYTE PTR [rbp-0x1],0x41
0x00000000004004f3 <+39>:    mov    eax,0x0
0x00000000004004f8 <+44>:    leave  
0x00000000004004f9 <+45>:    ret    
Run Code Online (Sandbox Code Playgroud)

当缓冲区为256字节时,为什么sub rsp只有0x98 = 152d?当我将数据移入缓冲区[0]时,它似乎只是使用分配的堆栈帧之外的数据并使用rbp来引用,那么甚至sub rsp的点是什么,0x98? …

assembly stack gcc x86-64

11
推荐指数
1
解决办法
2516
查看次数

编译器使用局部变量而不调整RSP

问题编译器:了解从小程序生成的汇编代码,编译器使用两个局部变量而不调整堆栈指针.

不调整RSP以使用局部变量似乎不会中断安全,因此编译器似乎依赖于硬件在发生中断时自动切换到系统堆栈.否则,出现的第一个中断会将指令指针推入堆栈并覆盖本地变量.

该问题的代码是:

#include <stdio.h>

int main()
{
    for(int i=0;i<10;i++){
        int k=0;
    }
}
Run Code Online (Sandbox Code Playgroud)

该编译器生成的汇编代码是:

00000000004004d6 <main>:
  4004d6:       55                      push   rbp
  4004d7:       48 89 e5                mov    rbp,rsp
  4004da:       c7 45 f8 00 00 00 00    mov    DWORD PTR [rbp-0x8],0x0
  4004e1:       eb 0b                   jmp    4004ee <main+0x18>
  4004e3:       c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
  4004ea:       83 45 f8 01             add    DWORD PTR [rbp-0x8],0x1
  4004ee:       83 7d f8 09             cmp    DWORD PTR …
Run Code Online (Sandbox Code Playgroud)

c linux x86 assembly x86-64

9
推荐指数
1
解决办法
330
查看次数

为什么编译器会保留一点堆栈空间而不是整个数组大小?

以下代码

int main() {
  int arr[120];
  return arr[0];
}
Run Code Online (Sandbox Code Playgroud)

编译成这样:

  sub     rsp, 360
  mov     eax, DWORD PTR [rsp-480]
  add     rsp, 360
  ret
Run Code Online (Sandbox Code Playgroud)

知道整数是 4 个字节,数组的大小为 120,数组应该占用 480 个字节,但从 ESP 中只减去了 360 个字节......这是为什么?

assembly x86-64 red-zone

1
推荐指数
1
解决办法
384
查看次数

EFLAGS 状态

在过去的几天里,我一直在为一种试图获得 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)

assembly x86-64 inline-assembly eflags

0
推荐指数
1
解决办法
74
查看次数

程序如何知道在堆栈上为局部变量分配多少空间?

在这个简单的函数中,为局部变量分配了空间。然后,变量被初始化并被printf调用以输出它们。

000000000040056a <func>:
  40056a:       55                      push   rbp                     ; function prologue
  40056b:       48 89 e5                mov    rbp,rsp                 ; function prologue
  40056e:       48 83 ec 10             sub    rsp,0x10                ; deallocating space for local variables
  400572:       8b 4d fc                mov    ecx,DWORD PTR [rbp-0x4] ; variable initialization
  400575:       8b 55 f8                mov    edx,DWORD PTR [rbp-0x8] ; variable initialization
  400578:       8b 45 f4                mov    eax,DWORD PTR [rbp-0xc] ; variable initialization
  40057b:       89 c6                   mov    esi,eax                 ; string stuff
  40057d:       bf 34 06 40 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly x86-64 stack-frame

0
推荐指数
1
解决办法
843
查看次数