【发布时间】:2019-04-21 01:20:18
【问题描述】:
我只需要使用 %rax、%rbx、%rcx、%rdx、%rsi 和 %rdi(还有 %rsp 和 %rbp)编写像素化汇编代码
所以我首先用 C 编写代码,并将任何其他寄存器更改为 64 位寄存器,但在下面我更改寄存器时,它提供了分段默认值
C 代码:
*temp = b;
*(temp + 1) = g;
*(temp + 2) = r;
gcc 的汇编代码:
movq -48(%rbp), %rax
movl %eax, %edx
movq -16(%rbp), %rax
movb %dl, (%rax)
movq -16(%rbp), %rax
addq $1, %rax
movq -56(%rbp), %rdx
movb %dl, (%rax)
movq -16(%rbp), %rax
addq $2, %rax
movq -64(%rbp), %rdx
movb %dl, (%rax)
将 %dl 更改为 %rdx:
movq -16(%rbp), %rax
movq -48(%rbp), %rdx
movzbq (%rdx), %rbx
movq %rbx, (%rax)
movq -16(%rbp), %rax
addq $1, %rax
movq -56(%rbp), %rdx
movzbq (%rdx), %rbx
movq %rbx, (%rax)
movq -16(%rbp), %rax
addq $2, %rax
movq -64(%rbp), %rdx
movzbq (%rdx), %rbx
movq %rbx, (%rax)
【问题讨论】:
-
你为什么要这样做?
-
鼓励打开编译器优化,顺便说一下,汇编输出会更短。
-
不清楚您要做什么以及为什么。无论如何,如果您只允许使用 64 位存储,如果您只想更新 3 个字节(然后您应该确保所有 8 个字节都可以访问),您将需要一个 read-modify-write。
-
%dl是%rdx的低字节。您确定您的教授不只是告诉您避免使用 RBX(在 x86-64 System V 调用约定中保留调用)和 R8..R15? -
好的,那么您所做的任何字节操作都必须使用 AND 掩码、移位和 OR。或者使用
movzbq从内存中加载。但是你不能做狭窄的商店。 (您可以读取/修改/写入一个 qword 并合并到一个新字节中,但这非常慢。如果您有多个相邻的字节存储要做,请先将它们合并到一个寄存器中并进行一个存储。)