• 一步
    置顶
    2021-12-19
    现在遇到了 汇编指令 比较多了,有些指令不知道做了什么, 有没有一个统一的地方可以方便进行查询的

    作者回复: 这是一个好问题,可以 watch 一下我在 01 讲的提到的 GitHub 仓库哈,我会尽快把相关资料更新在里面的。

    共 2 条评论
    4
  • liu_liu
    2021-12-15
    关于迭代语句中的 .L2 汇编代码段: // 把 v 放入 eax mov eax, DWORD PTR [rbp-4] // edx = rax-1 lea edx, [rax-1] // 把 edx 的值写入 rbp-4 地址 move DWROD PTR [rbp-4], edx 这段汇编的作用应该是用于 v-- 。 但有一些不太明白,为什么要使用 lea 指令呢?可直接用 move 指令?

    作者回复: 这是一个很棒的问题! 如果使用 mov 指令,也是可以完成同样的功能的,只不过需要独立的两条指令,比如: - dec rax; - mov edx, rax 但使用 lea 指令,我们就可以仅通过一条机器指令来实现。相对于前者,其执行效率是不是更高呢?实际上,对于编译器来说,很多基本的四则运算都可以直接使用 lea 指令来实现,比如 lea eax, [123 + 4*ebx + esi],就是直接将 ebx 中的值乘以 4 再加上 123 和 esi 中的值。相较于使用 mov 的多条指令,lea 可以充分利用它在硬件中的电路特性,以更高的效率进行计算。

    
    10
  • pedro
    2021-12-13
    竟然有一种像当年读CSAPP第三章的感觉! 空语句用的少,多数时候用来做空循环体吧。

    作者回复: 没错!这是一种常见的场景。举个例子: #include <stdio.h> int main() { char c; while ((c = getchar()) == ' '); printf("%c", c); }

    
    5
  • 送过快递的码农
    2021-12-15
    老师 ,test/cmp 比较多指令,最终结果会在EFLAGS这个寄存器中么,j(cond)指令会根据这个寄存器做相应的跳动?

    作者回复: 没错的,你的理解是正确的。

    
    2
  • qinsi
    2021-12-13
    维基上Duff's device的例子 send(to, from, count) register short *to, *from; register count; { register n = (count + 7) / 8; switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while (--n > 0); } }

    作者回复: 达夫设备是 switch 语句和循环展开的巧妙结合,我们会在 19 讲再来深入介绍哈!

    
    2
  • 阿妞
    2022-08-31 来自江苏
    老师,请问一下 下面代码的汇编,满足条件跳转到.L6,不满足就继续执行,但最后的v=20,是在.L6里面,只有跳转才执行,不跳转就不执行?从c上看,是无论满足不满足条件,都应该执行的呀,很疑惑! int test() { int v=20; if(v>10) { v--; v=10; } v=20; } test: push rbp mov rbp, rsp mov DWORD PTR [rbp-4], 20 cmp DWORD PTR [rbp-4], 10 jle .L6 sub DWORD PTR [rbp-4], 1 mov DWORD PTR [rbp-4], 10 .L6: mov DWORD PTR [rbp-4], 20 nop pop rbp ret

    作者回复: 不跳转就会继续顺序执行,也是会执行到 .L6 位置的代码的。

    共 2 条评论
    
  • 白花风信子
    2021-12-18
    进程里面的挂起也是for(;;);叭

    作者回复: 如果这里提到的“挂起”是指阻塞当前线程的话,可以使用 poll \ select \ semaphore 等方式哈。死循环并不是一个好的方式。

    
    
  • 友
    2021-12-17
    像 edi esi 对应的应该是 第一个参数 第二个参数吧 ~ 我记得有 6个还是7个寄存器可以用来传参

    作者回复: 没错的,我们在第 05 讲有介绍这些内容哈。

    共 2 条评论
    
  • chinandy
    2021-12-14
    老师:高优化等级怎么打开,在您给的那个网站上

    作者回复: 可以直接在上方的 “Compiler options” 输入框里输入对应优化等级的参数,比如:-O2 \ -O3。

    
    
  • Geek_828b39
    2021-12-14
    将寄存器 rdx 中的值左移 v 位(值被扩展为 64 位); 老师,这个这么理解?

    作者回复: 这里实际上是跟蓝框内的第一条汇编语句做的对比。第一条的 mov 指令仅把值 1 当做 32 位值放入到 edx 中;而后续程序在使用这个值生成“token”时,实际上是直接用 rdx 来访问的,因此实际上是在进行左移时同时被“扩展”为了 64 位值。同样的,后面进行按位与时,也是直接以 64 位值进行的。

    
    