那么在汇编中,如何e[]x在16位实模式下可以使用,而r[]x在32位模式下不能使用呢?例如:
BITS 16
mov bx, 1
mov eax, 2
Run Code Online (Sandbox Code Playgroud)
将在 IDA 中正确组装和反汇编(在 16 位模式下)。它可以工作,因为我之前已经反汇编了 Win2k 引导加载程序并找到了eax.
但是,为什么即使在无法访问的受保护模式下的 64 位处理器上也无法访问r[]x?
在 x86_64 中,没有 64 位地址的直接跳转。只有一个 32 位的。通过间接跳转,我理解在分支预测发挥作用之前必须解决管道一次。我的问题是:在 64 位中没有办法在第一次执行时进行 1-3 个周期的跳转吗?
如何仅使用英特尔 64 位汇编和 nasm 汇编器创建/处理用一种颜色填充的简单 bmp 文件?
我真的需要一些帮助。我已经在网上搜索了大约 2 天,似乎无法找到我遇到的问题的答案。
我下载了 nasm 并安装了它,它似乎可以工作,但我似乎找不到任何适用于 Windows 64 位的示例代码(如果你能为我或其他东西制作一个简单的 hello world 示例,那就太棒了)。(以及如何编译它)
我如何将 .o 文件变成 .exe?
我将如何访问屏幕或 GPU 内存(我认为)以在屏幕上打印内容(例如某种控制台应用程序)?
我一直在努力学习为 AMD64 处理器编写汇编代码。我一直在看 gcc 生成的代码。最终,我开始看到诸如
call *(%rax)
Run Code Online (Sandbox Code Playgroud)
操作数前面的 * 是做什么的?我正在阅读的 System V ABI 文档中出现了类似的内容,上述问题的答案将帮助我继续。以下是上下文中使用的语法示例,取自 System V ABI 文档本身:
// System V ABI suggested implementation of a
// C switch statement with case labels 0, 1, and 2,
// and a default label.
// Jump to the default case if the control variable is
// less than 0.
cmpl $0, %eax
jl .Ldefault
// Jump to the default case if the control variable is
// greater than 2.
cmp $2, %eax …Run Code Online (Sandbox Code Playgroud) 我在汇编中编写了一个程序,如下所示:
%macro print 1
push rbp
mov rdi, %1
xor rax, rax
call _printf
pop rbp
%endmacro
section .data
e db 'Equal', 0
l db 'Less than', 0
g db 'Greater than', 0
section .text
global start
extern _printf
start:
mov rax, 5
mov rbx, 5
cmp rax, rbx ; Compare 4 and 5
je _equal ; je = jump if equal
cmp rax, rbx
jl _less ; jl = jump if less
cmp rax, rbx
jg _greater ; jg …Run Code Online (Sandbox Code Playgroud) 我正在创建一个文件,然后使用系统调用打开它。
创建:
mov rax, 85
mov rdi, path
mov rsi, 400
syscall
Run Code Online (Sandbox Code Playgroud)
开幕:
mov rax, 2
mov rdi, path
mov rsi, 2 ; I found somewhere that I should use 400 to append
syscall
mov r8, rax ; save the file handle
Run Code Online (Sandbox Code Playgroud)
写作:
mov rax, 1
mov rdi, r8
mov rsi, output
mov rdx, length
syscall
Run Code Online (Sandbox Code Playgroud)
完成这些步骤后,我自然地关闭了文件,但是我无法附加到它,每次执行这些操作时它只会重写文件的内容,但是例如我计算了前 n 个素数并将它们存储在一些内存块,现在我想在文件中写下这 n 个素数,但如果不附加更多行,我就无法这样做。
还有一种方法可以不为writein指定字符串的长度rdx,而是让字符串以/0?
如何使用 asm() 将 32 位值写入寄存器 r8-r15 的低位双字?以下代码无法编译:
#include <stdlib.h>
#include <stdio.h>
int main()
{
float f0,f1,f2=-2.4f;
asm volatile
(
"movl %2, %%r8\n"
"movl %%r8, %1\n"
"movl %1, %%r15\n"
"movl %%r15, %0"
:"=r"(f0,f1)
:"r"(f1,f2)
:"%r8,%r15"
);
printf("%f\n",f0);
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
unknown register name '%r8,%r15' in 'asm'
Run Code Online (Sandbox Code Playgroud)
请注意,它是一个 x64 程序,因此 r8-r15 寄存器应该可用。
这个想法是,我想收集的返回的值double成一个矢量寄存器,用于机加工imm width在一个时间而不第一存储回到存储器。
特定的处理vfma与其他两个操作数都是constexpr,因此它们可以简单地由_mm256_setr_pd调用或从 中对齐/未对齐的内存加载constexpr array。
有没有办法%ymm直接从 value in 中将double 存储在特定位置以%rax进行收集?
目标机器是 Kaby Lake。更有效的未来向量指令也是受欢迎的。
我已经做了这个代码:
global strlen
; int strlen(const char *string);
strlen:
xor rcx, rcx
retry:
cmp byte [rdi + rcx], 0
je result
inc rcx
jmp retry
result:
mov rax, rcx
ret
Run Code Online (Sandbox Code Playgroud)
这就是我测试它的方式:
#include <stdio.h>
int main(int argc, char **argv)
{
char* bob = argv[1];
printf("%i\n", strlen(bob));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是一个有效的 strlen,这里没问题,但我注意到我可以rdi在重试块的第一行切换arax而不改变任何东西,我不知道这是否是正常行为。我应该保留哪些值?