我使用 64 位程序集并有两个不同的文件。其中一个文件更改了字符串,以便该字符串添加了随机的新字符。另一个文件包含一个数组。
这是来自编辑字符串的文件:
returnString:
mov rax, newString
ret
这是数组及其设置方式:
section .bss
array: resq 4
allocString: resb 128
section .text
_start:
mov qword[array], defaultMes0
xor r8,r8
add r8, 8
mov qword[array + r8], defaultMes1
add r8, 8
mov qword[array + r8], defaultMes2
add r8, 8
mov qword[array + r8], defaultMes3
add r8, 8
这是应该将字符串从函数移动到数组中的函数:
rev:
mov rax, 8
movzx rdx, byte [index] ; Clear rdx to avoid issues with imul
imul rdx ; Multiply index by 8
mov rdi, qword [array + rax]
call stringEdit
lea rbx, [allocString]
translateLoop:
mov dl, [rax]
mov [rbx], dl
;both incremented and counter also incremented
inc rax
inc rbx
;comparison, if less than bl then done until it is equal to enterNum (place of split)
cmp byte[rax], 0x0
jne translateLoop
mov rax, 8
movzx rdx, byte [index] ; Clear rdx again
imul rdx ; Multiply index by 8
mov qword [array + rax], rbx
如果使用 print 函数输出字符串,它将是空白的(例如,它不会输出任何内容)。
我尝试过:
returnString:
mov rax, [newString]
ret
但它无法正常工作。我还尝试将函数的输出直接放入字符串中,如下所示,但这也不起作用(无论是引用还是取消引用 newString 时)。如果取消引用 newString,则在打印时会导致段错误,并且如果未引用,则调用该函数的任何其他时间,数组中的所有内容都指向同一对象,因此调用此函数的任何数组索引都将共享相同的结果.
call stringEdit
mov qword [array + rax], rdi ;;moved it to the rdi before
我尝试过做
returnString: mov rax, [newString] ret
这将返回新字符串内容的前八个字节。您的第一次尝试是正确的,
mov rax, newString
返回新字符串的地址。
mov qword[array], defaultMes0 xor r8,r8 add r8, 8 mov qword[array + r8], defaultMes1 add r8, 8 mov qword[array + r8], defaultMes2 add r8, 8 mov qword[array + r8], defaultMes3 add r8, 8
您无法将 64 位立即数移至内存,并且 R8 的使用过于复杂,因为您可以更轻松地使用
+8
、+16
和 +24
进行偏移。
lea rax, [rel defaultMes0]
mov [rel array], rax
lea rax, [rel defaultMes1]
mov [rel array + 8], rax
lea rax, [rel defaultMes2]
mov [rel array + 16], rax
lea rax, [rel defaultMes3]
mov [rel array + 24], rax
mov rax, 8 movzx rdx, byte [index] ; Clear rdx to avoid issues with imul imul rdx ; Multiply index by 8 mov rdi, qword [array + rax]
对于基于 index 变量 [0,3] 的读写,最好使用缩放索引寻址模式,而不是单独乘以 8:
movzx ecx, byte [index] ; Load RCX with index [0,3]
mov rdi, [array + rcx * 8]
lea rbx, [allocString] translateLoop: mov dl, [rax] mov [rbx], dl inc rax inc rbx cmp byte[rax], 0x0 jne translateLoop mov rax, 8 movzx rdx, byte [index] imul rdx mov qword [array + rax], rbx ; (*)
这里有一些错误:
call stringEdit ; -> RAX
lea rbx, [rel allocString]
movzx ecx, byte [index] ; Load RCX with index [0,3]
mov [array + rcx * 8], rbx
copyLoop:
movzx edx, byte [rax]
mov [rbx], dl
inc rax
inc rbx
cmp byte [rax - 1], 0
jne copyLoop
如果使用 print 函数输出字符串,它将是空白的(例如,它不会输出任何内容)。(*) 当地址指向字符串后面时就是您所期望的。