【发布时间】:2018-03-30 18:39:48
【问题描述】:
我正在尝试将我的 C 代码转换为 x86-64。我的目标是反转一个链表。传入的两个参数是头 ptr 和偏移量,以获取指针字段的地址(即指向列表中下一个节点的指针)。
据我了解,head ptr是通过rdi寄存器传入的,offset是通过rsi寄存器传入的。当它到达“mov rcx,[rbx]”行时,我不断收到分段错误。当它只是“mov rcx, rbx”并且后面的行从“mov [rbx], rdx”更改为“mov rbx, rdx”时,分段错误就消失了。但是,我最终陷入了无限循环,因为它只是一遍又一遍地简单地分配相同的值。
当我跟随我的 C 代码时,x86-64 中的所有逻辑对我来说都是有意义的,所以我真的处于停滞状态。有任何想法吗?这是我第一次使用 x86-64。
.intel_syntax noprefix
.text
.global reverse_asm_64
reverse_asm_64:
push rbx
push r12
mov rax, 0x0
#headptr
mov rbx, rax
#nextptr
mov rcx, rax
#new_headptr
mov rdx, rax
#head
mov rax, [rdi]
#checks if head is null
cmp rax, 0
je null_ret
#move offset into a register
mov r12, rsi
add rax, r12
#add offset to rax to get the next ptr
mov rbx, rax
while_start:
#checks that next ptr isn't null
cmp rbx, 0x0
je while_done
#setting the next ptr
mov rcx, [rbx]
# *headptr = new_headptr
mov [rbx], rdx
#new_headptr = headptr
mov rdx, rbx
#sets headptr to nextptr
mov rbx, rcx
jmp while_start
while_done:
mov rax, rdx
sub rax, rsi
null_ret:
pop r12
pop rbx
ret
【问题讨论】:
-
这种看似无用的练习有充分的理由吗?
-
有一些工具对此非常有用:C 编译器。他们中的许多人可以选择发出汇编代码,而那些没有的可以与反汇编程序配对。
-
很高兴有人同意这是一个无用的练习。我需要完成课堂作业,但过去几天我一直卡住了。
-
您没有发布您的 C 代码,但第一个整数/指针参数在
rdi中传递,第二个在rsi中传递。什么是“抵消”?进入链表的位置?你的汇编很难阅读;缩进你的说明而不是标签。此外,与指令在同一行的 cmets 使事情更加紧凑。 -
另外,您不需要保存/恢复 rbx 和 r12。您可以使用 r8、r9、r10 和 r11 作为临时注册,以及 rax/rcx/rdx/rsi/rdi。
标签: c assembly x86-64 inline-assembly