c语言48位的负数怎么存储到64位变量,关于汇编:如何仅使用64位寄存器将1字节值存储在64位寄存器中?...

我只需要使用%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个字节都可以访问),则需要进行读-修改-写操作。

真的没有办法摆脱movb %dl, (%rax)。我不知道这个练习的目的是什么。也许你误解了。

@用户202729这是因为教授不希望我们只转换C代码,而是使用汇编语言。因此可用寄存器受到限制:/

不能用64B寄存器存储来存储1个字节的值。(您可以通过先读取其他7个字节,然后只修改一个字节来修改一个字节,但在任何情况下,写入都将是8个字节)而且您的问题毫无意义,C->ASM没有使用优化等…听起来太像问题xy的情况了。(编辑:如果这是关于"像素",这些通常是一个连续的数组,所以您应该将其填充到足够的位置,以允许8个字节的写入覆盖一个位,同时处理8个字节,以便每8个值只存储一次)。从性能的角度来看,这也是有意义的。

@seokyoungkook哪些寄存器可以使用?

@用户202729%rax%、rbx%、rcx%、rdx%、rsi和%rdi(也包括%rsp和%rbp)

@然后,seokyoungkook编辑问题以指定只能使用那些(64位)寄存器。//还有什么是temp,位置*(temp+3)、*(temp+4)等的内存可以访问吗?

@fuz教授告诉我们尝试>%rax、%rbx、%rcx、%rdx、%rsi和%rdi(也包括%rsp和%rbp)

如果您需要处理8位值,但是在64B组中,您必须在更高的层次上考虑它,就像整个循环处理所有值一样。您所要求的方式根本不可能,或者以非常无效的方式(使用临时缓冲区char temp[8+3];甚至更多),然后在稍后处理temp的3个字节,从而浪费了许多机器周期来写入比需要的内存多得多的内存。

%dl是%rdx的低位字节。你确定你的教授不仅仅是告诉你要避免RBX(它是保存在x86-64 SystemV调用约定中的调用)和R8..R15吗?

@Ped7g我认为我需要从一开始就考虑到你的评论…太天真了:只学了一个月的汇编代码,通常我都不知道自己在做什么,哈哈。

@彼得遗憾地拒绝了:甚至不允许使用%eax%、ax%、al和任何其他。如果我们想从内存中读取1个字节,我应该尝试>>movzbq(%rdi),%rax

好的,那么您所做的任何字节操作都必须使用和屏蔽、移位和或。或者使用movzbq从内存加载。但你不能在狭窄的商店里购物。(你可以读/修改/写一个Qword,然后合并成一个新的字节,但是速度非常慢。如果要进行多个相邻字节存储,请先将它们组合到一个寄存器中,然后进行一个存储。)

我想你想做点什么:

t = r & 0xff;

u = *temp & ~ 0xfful;

*temp = u | t;

t = (g & 0xff) << 8;

u = *temp & ~ 0xff00ul;

*temp = u | t;

t  = (b & 0xff) << 16;

u = *temp & ~0xff00000ull;

*temp = u | t;

您应该只能用64位regs编写这个命令。你也应该能找到很多方法来让这个方法比这个小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值