为什么这个汇编代码不能自行修改

时间:2014-12-28 11:38:09

标签: assembly self-modifying

我想知道汇编中的自修改代码是否可行,因为.text是只读的我认为我可以将代码放在.data中,我尝试了下面的代码。

section     .text
global      _start                            ;must be declared for linker (ld)

_start:                                       ;tell linker entry point

    mov al,3
    mov rbx,cont1                             ;store label cont1 in rbx so we can continue there
    mov cl,byte [dec_op]                      ;put the opcode of the dec instruction in cl
    mov byte [code],cl                        ;replace the inc instruction with a dec instruction
    jmp code                                  ;run the modified code
cont1:
    mov byte [dat1],al                        ;store away the changed value
    add byte [dat1],0x30                      ;turn the internal numeric value into an ascii digit
    mov eax,4                                 ;system call number (sys_write)
    mov ebx,1                                 ;stdout
    mov ecx,dat1                              ;location of data
    mov edx,2                                 ;length of data
    int 0x80                                  ;call kernel

    mov     eax,1                             ;system call number (sys_exit)
    int     0x80                              ;call kernel

section     .data

dat1        db 0,0xa                          ;location to store output
dec_op      dec al                            ;the dec instruction
code        inc al                            ;code to modify
            jmp rbx

以上的输出是

4

虽然我期望2,但是在修改之后,它应该有一个减少指令而不是增加指令。我做错了什么?

我正在运行debian sid 64位,我正在编译:

nasm -f elf64 sm.s
ld -s -o sm sm.o

1 个答案:

答案 0 :(得分:4)

这是因为DEC AL需要2个字节

来自nasm生成的“listfile”的

(略微浓缩的列):

 26 00000000 000A     dat1        db 0,0xa                ;location to store output
 27 00000002 FEC8     dec_op      dec al                  ;the dec instruction
 28 00000004 FEC0     code        inc al                  ;code to modify
 29 00000006 FFE3                 jmp rbx

可以看出,两个操作码的第一个字节是相同的,因此存在混淆。

这就是解决方法。

    mov cx,word [dec_op]                      ;put the opcode of the dec instruction in cl
    mov word [code],cx                        ;replace the inc instruction with a dec instruction