assembly 如何更改x86_64程序集(nasm)中的变量值

zvms9eto  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(191)

我正在尝试更改x86_64 asm中的变量值
这是我的方法

section .data
    text db "Hello, World!",10
   
 
section .text
    global _start
 
_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, text
    mov rdx, 14
    syscall

    mov rax , "He"

    mov  [text], rax
    syscall
   
    

    mov rax, 1
    mov rdi, 1
    mov rsi, text
    mov rdx, 14
    syscall

    mov rax, 60
    mov rdi, 0
    syscall

但它输出

Hello, World!
Heorld!

我试着用途:mov word [text], "He"但那也不起作用

dddzy1tm

dddzy1tm1#

不管存储器修改后的syscall是否为奇数,输出原因如下,最初text地址的字节为:

0  1  2  3  4  5   6  7  8  9  a  b  c  d

48 65 6c 6c 6f 2c  20 57 6f 72 6c 64 21 0a
 H  e  l  l  o  , ' ' W  o  r  l  d  ! \n

之后

mov rax , "He"

rax在两个低位字节中包含0x6548,其他六个字节归零。由于x86_64为小端序,因此在

mov  [text], rax

记忆是:

0  1  2  3  4  5  6  7  8  9  a  b  c  d

48 65 00 00 00 00 00 00 6f 72 6c 64 21 0a
 H  e \0 \0 \0 \0 \0 \0  o  r  l  d  ! \n

终端上不打印零字节。

bxfogqkk

bxfogqkk2#

变量是一个标签,它基本上保存了值在内存中的地址。当你想改变值时,你需要使用方括号[],并取消引用指向该位置的地址。然后你就可以一个接一个地改变值。例如,让我们定义一个单字节变量:

v: db 0x00

要更改值,可以执行以下操作

mov byte[v], 0x02

如您所见,我们使用byte指定了大小
如果我们有以下变量:

abc: dw 0x0000

变量abc只保存数据的第一个字节的地址,但数据本身是一个字(2个字节)。这就是为什么要更改变量的值,我们需要执行以下操作:

mov word[abc], 0xDEAD

这相当于

mov byte[abc], 0xAD
mov byte[abc+1], 0xDE

请注意,2字节值的最小第一个字节位于较早的内存地址中,这称为小端顺序。
一个字符串本质上是一串“字节”,彼此相邻(它不使用小端序)。要逐个更改字符串值,可以执行以下操作:

text: db "Hello World", 0

mov byte [text], 'A' ; Aello World
mov byte [text+1], 'B' ; ABllo World
mov byte [text+2], 'C' ; ABClo World
; and etc

最后我们也可以看看你的代码:

text db "Hello, World!",10
   
mov rax , "He"
mov [text], rax
syscall

这是无效的(正如@vitsoft所指出的),因为在调用syscall之前,您将"He"放在了rax中,syscall使用rax来确定它要做什么。
事实上这行代码

mov word [text], "He"

是完全有效的。我不知道为什么你不能让它工作。"He"本质上被解析为0x6548,你把一个普通的mov当作一个单词。就像我之前提到的,因为单词的小端顺序,X1 M10 N1 X将被放置在已经是X1 M12 N1 X的X1 M11 N1 X的第一字节中,并且类似地,X1 M13 N1 X将被放置在已经是X1 M15 N1 X的X1 M14 N1 X的第二字节中。
编辑:
假设你不知道要复制到另一个字符串/位置的字符串的长度。在这种情况下,你应该循环遍历该字符串,并逐个修改。我将在这里留下一个示例代码,你需要修改和修改:

start:
    xor ecx, ecx ; initialize some variable to keep count

.loop:
    mov al, byte [other + rcx] ; get the nth character of other.
    cmp al, 0x00 ; if we reached the end of the string
    je endLoop ; end the function
    mov [text + rcx], al ; write the nth character of other to nth position of text
    inc ecx ; increase counter
    jmp .loop ; loop

endLoop:
    ret

text: db "Hello World", 0
other: db "ABC", 0

相关问题