的运算ADC是DEST ? DEST + SRC + CF, 的运算SBB是DEST ? (DEST – (SRC + CF))。让我感到困惑的是这些指令对 FLAGS 的影响。在 的情况下SBB,结合性是明确的,因此我假设它SBB等于(最终的寄存器状态)
jnc label
lea src, [src+1]
sub dest, src
lea src, [src-1]
jmp label2
label:
sub dest, src
label2:
Run Code Online (Sandbox Code Playgroud)
但是,在 , 的情况下ADC,将SRC首先添加到DEST,然后在其之上CF添加?这很重要,因为如果是这样,它会对 FLAGS 产生不同的影响。
我想知道 void 指针是如何实现的。我试图用 x86-64 在 Godbolt 上找到它(你可以在这里看到它),但它没有透露任何信息。空指针是如何实现的?
编辑: 这是我使用的代码:
int main() {
int volatile y = 123;
void* volatile x = &y;
}
Run Code Online (Sandbox Code Playgroud)
我想在这里看到的只是它的x样子。我放置了 volatile 以便 gcc 不会将其作为死代码消除。
我最近尝试编译一个 C++ 程序,但发现它给出了这个错误:
Undefined symbols for architecture x86_64:
"std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
std::__1::ctype<char> const& std::__1::use_facet<std::__1::ctype<char> >(std::__1::locale const&) in test-c64d7d.o
"std::__1::ios_base::getloc() const", referenced from:
std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in test-c64d7d.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)", referenced from:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(unsigned long, char) in test-c64d7d.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) in test-c64d7d.o
"std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)", referenced from:
std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, …Run Code Online (Sandbox Code Playgroud) 我正在阅读一本教科书,其中有一个基于 C 代码生成汇编代码的练习:
代码:
long arith(long x, long y, long z)
{
long t1 = x ^ y;
long t2 = z * 48;
long t3 = t1 & 0x0F0F0F0F;
long t4 = t2 - t3;
return t4;
}
Run Code Online (Sandbox Code Playgroud)
汇编代码:
//x in %rdi, y in %rsi, z in %rdx
arith:
xorq %rsi, %rdi //t1 = x ^ y
leaq (%rdx,%rdx,2), %rax //3*z
salq $4, %rax //t2 = 16 * (3*z) = 48*z
andl $252645135, %edi //t3 = t1 & 0x0F0F0F0F …Run Code Online (Sandbox Code Playgroud) assembly bit-manipulation x86-64 instruction-set instructions
我想让 Linux 只使用 sys_read 从键盘上进行 1 次击键,但 sys_read 只是等到我按下 Enter 键。如何读取 1 个按键?这是我的代码:
Mov EAX,3
Mov EBX,0
Mov ECX,Nada
Mov EDX,1
Int 80h
Cmp ECX,49
Je Do_C
Jmp Error
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用 BIOS 中断但它失败了(分段错误),我想从键盘捕获数字 1 到 8 输入。
我一直在寻找堆栈溢出,但似乎找不到任何东西
Windows 64 位上的 kernel32.dll 中的哪些命令和函数可以在屏幕上绘制单个像素,最好没有 user32.dll 窗口?
它只是分配一个包含 1000000 个整数的数组和另一个整数,并将数组的第一个整数设置为 0
我编译这个使用 gcc -g test.c -o test -fno-stack-protector
显然,它在循环中不断在堆栈上分配 4096 个字节,并且每 4096 个字节与 0“或”,然后一旦达到 3997696 个字节,它就会进一步分配 2184 个字节。然后继续将第 4000000 个字节(从未分配过)设置为 5。
为什么不分配请求的全部 4000004 字节?为什么它在每 4096 个字节“或”一个 0,这是一条无用的指令?
我在这里理解错了吗?
注意:这是用 gcc 9.3 版编译的。gcc 7.4 版不执行循环和“或”每 4096 个字节为 0,但它只分配了 3997696+2184=3999880 个字节,但仍将第 4000000 个字节设置为 5
浏览 Zydis(https://github.com/zyantific/zydis/blob/57be5b1d1b9dd99830b89caac928add64ad5d072/include/Zydis/Generated/EnumMnemonic.h)助记符我发现了这些:
ZYDIS_MNEMONIC_JKNZD,
ZYDIS_MNEMONIC_JKZD,
Run Code Online (Sandbox Code Playgroud)
我在其他任何地方都找不到这些助记符;它们代表什么指令?
这些指令执行什么操作?
ZandNZ可能分别表示零和不为零,并且J可能代表跳跃,但是K和D?
编辑:我找到了这个旧的英特尔文档,但没有任何意义:
它指出(第 75 页)JKZD 被编码为 VEX.NDS.128.0F.W0 84 id。
我发现自己经常无法立即识别数字是十进制还是十六进制(如果十六进制数字没有前缀或字母)。例如,从上一个问题中得到一个喜欢0000000000400078但不确定是哪个的数字。
有没有办法在 x86_64 中明确指定带有前缀的十进制数?例如:
mov %rsp, %rbp
movb $0x16, -1(%rbp)
movb $0d22 -2(%rbp) # <-- something like this
movb $0b10110, -3(%rbp)
Run Code Online (Sandbox Code Playgroud)
我知道这样做movb $22, -2(%rbx)有效,但是有没有办法明确地为它加上前缀/后缀,以便我们知道它是小数?
我正在尝试编写以下形式的函数:
void swap(int *a, int *b);
在 x86-64 汇编中。
[section .text]
global swap ;
swap: mov ecx, [esp+8] ; copy parameter a to ecx
mov edx, [esp+16] ; copy parameter b to edx
mov eax, [ecx] ; copy a into eax
xchg eax, [edx] ; exchange eax with b
mov [ecx], eax;
ret;
Run Code Online (Sandbox Code Playgroud)
我使用以下命令在 Linux 上编译它:
Run Code Online (Sandbox Code Playgroud)nasm -f elf64 swap.asm
它编译没有任何错误。主要文件如下:
#include <stdio.h>
extern void swap(int *a,int *b);
int main(){
int a = 10, int b = 20;
swap(&a,&b);
printf("a …Run Code Online (Sandbox Code Playgroud)