gpt4 book ai didi

c - 在字符串操作中使用 DI 寄存器

转载 作者:行者123 更新时间:2023-11-30 20:14:45 27 4
gpt4 key购买 nike

我正在查看 C 程序的编译器输出,只是出于学术目的,并且碰巧得到了以下输出。

 .file   "test.c"
.section .rodata
.LC0:
.string "Hello World"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits

我了解基于指针和堆栈指针操作发生的部分以及其他操作,我想知道 put 有什么用

movl    $.LC0, %edi

如何将测试“Hello world”的地址从数据 block 加载到目标寄存器中解决这个问题,我们可以将该地址加载到累加器中并让 printf 处理它。我不习惯用汇编语言编程,但我可以弄清楚程序在做什么,我是否在这里遗漏了一些明显的东西?谷歌搜索显示它们用于字符串操作,但没有人说为什么?

最佳答案

首先,您对 printf 的调用可能通过寄存器而不是堆栈传递参数,因为它是以这种方式优化的,或者因为它在编译期间的属性设置为 __fastcall (MSVC) 或 __attribute__((fastcall))

%esi%esi 寄存器用于字符串操作,因为它们对字符串指令具有意义,例如 cmps lodsmovsscasstosoutsins 。这些指令使用目标和源寄存器来快速顺序访问字节/字/双字字符串。它们可以在循环中使用,以进行已知在内存中连续执行的简单操作,并且通过消除指针操作和限制检查的需要,与循环前缀结合可以缩短执行时间。

一个很好的例子是 movs 指令(它还有另一种形式,如 movsbmovswmovsd)。如果您想编写一个没有字符串指令的简单字符串复制过程,您可以编写如下内容:

; IN: EAX=source&, EBX=dest&, ECX=count
; OUT: nothing
copy:
.loop:
cmp ecx, 0
jz .end

dec ecx
mov al, byte [eax+ecx]
mov byte [ebx+ecx], al
jmp .loop
.end:
ret

movsb 指令将 [esi] 复制到 [edi],并递增 esiedi,然后递减 ecx。考虑到这一点,您可以编写类似的内容:

; IN: ESI=source&, EDI=dest&, ECX=count
; OUT: nothing
copy:
.loop:
jecxz .end
movsb

jmp .loop
.end:
ret

使用循环前缀,您可以再次加快整个操作的速度

; IN: ESI=source&, EDI=dest&, ECX=count
; OUT: nothing
copy:
rep movsb
ret

关于c - 在字符串操作中使用 DI 寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24742381/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com