Assembly 创建For循环以填充程序集中充满破折号的空缓冲区
这就是我到目前为止得到的,每次我到代码的循环部分,我都会得到Assembly 创建For循环以填充程序集中充满破折号的空缓冲区,assembly,x86,att,Assembly,X86,Att,这就是我到目前为止得到的,每次我到代码的循环部分,我都会得到分段错误(内核转储)。这是因为我的一些寄存器保存的东西大小不正确吗 .data Welcome: .ascii "Welcome to League of Legends!!.\n\0" Instruction: .ascii "Player 1, enter a Champion's name: \0" Text: .space 12 Text2: .
分段错误(内核转储)
。这是因为我的一些寄存器保存的东西大小不正确吗
.data
Welcome:
.ascii "Welcome to League of Legends!!.\n\0"
Instruction:
.ascii "Player 1, enter a Champion's name: \0"
Text:
.space 12
Text2:
.space 12
Guess:
.ascii "Guess a letter: \0"
Letter:
.space 1
SecretCharacter:
.ascii "Your Champion is: \0"
.text
.global _start
_start:
mov $Welcome, %rax
call PrintCString
mov $Instruction, %rax
call PrintCString
mov $Text, %rax
mov $12, %rbx
call ScanCString
mov %rax, %rbx
mov %rax, %rbp
call LengthCString
mov %rax, %rcx
mov $0, %rdi
mov $45, %ch
Loop:
cmp %rcx, %rdi
jge End
mov $Text2, %eax
movb %ch, (%rax, %rdi)
add $1, %rdi
jmp Loop
End:
call PrintCString
call EndProgram
您同时使用rcx和ch,但ch是rcx的一部分。尝试使用dh而不是ch。
mov$Text2,%eax
应该是mov$Text2,%rax
。此外,它应该在循环上方而不是内部。@prl:是的,它应该在循环外部,但在Linux上,静态地址保证在低32位的地址空间中,因此使用5字节零扩展的mov r32、imm32
而不是7字节的mov r/m64、符号扩展的-imm32
可以节省代码大小。(GAS不会为您进行优化,即使是像$1
这样的数值常量,更不用说链接时间常量了)。对于独立于位置的可执行文件(或者即使不需要PIC,静态地址也不适合32位的OS X),您可以使用leatext2(%rip),%rax
。那么,在这种情况下,mov$Welcome,%rax
和其他一些错误。我知道是这样或那样的。@prl:好吧,反正效率很低。但是,对于一个不关心效率的初学者来说,这和mov$0、%rdi并不是“错误的”,尽管如此。@Bobbin:或者更好,%dl
避免了。通常,加载完整寄存器后,仅使用AH/BH/CH/DH获取较大值的字节。(例如,mov(%rdi),%eax
;movzbl%al,%ecx
;movzbl%ah,%edx
;shr$16,%eax
;…)@PeterCordes当您始终分别使用低部分和高部分时,使用ah、bh、ch和dh不是很好吗?@fuz:在至少分别重命名高部分寄存器的CPU上,是的。(在AMD和Silvermont/KNL上,书写ah
/al
都在rax上有一个错误的dep(因此彼此都有)。在HSW/SKL上,可能会消耗额外的物理寄存器文件条目。我认为虽然它很脏,但重复阅读它并没有延迟惩罚。但是如果中断处理程序保存/恢复它,中断处理程序将遭受合并uop的惩罚,合并uop必须在一个周期内自行发出,然后在合并后读取DH会有额外的1c延迟。很小,但严格来说比DL@PeterCordes正如图所示,低寄存器并不是严格地优于高寄存器:因为它们是单独重命名的,所以在重写时可以避免持续的错误依赖(例如,mov
到ah
可以以4/周期运行,但是mov
到al
每个周期仅运行1个,因为它错误地依赖于eax
的高位),虽然这在这里并不重要。@BeeOnRope:是的,使用mov-ah,r/m8
,但不使用mov-ah,imm8
或setcc-ah
。但是如果您正在编写可移植的性能代码,您必须为Ryzen或任何在RAX上编写ah时总是有一个错误的dep的地方做好准备。所以是的,低8个reg并不总是更好或相等l比high8高,但一般来说,我绝对建议不要写入high8寄存器,除非你有理由。