我想知道汇编中的自修改代码是否可行,因为.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
答案 0 :(得分:4)
这是因为DEC AL
需要2个字节
(略微浓缩的列):
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