String ARMv6上的STRB指令导致程序崩溃
在学习ARMv6 ASM(使用raspberry pi)时,我试图实现一个修改字符串内容的循环,但是我似乎无法将修改后的字节存储回内存。 使用GDB并在不同的点上断开显示,在STRB指令出现之前,所有注册表值都能正常工作。然后它因为未知的原因崩溃了。 循环应按相反顺序将所有字节递减1String ARMv6上的STRB指令导致程序崩溃,string,assembly,arm,String,Assembly,Arm,在学习ARMv6 ASM(使用raspberry pi)时,我试图实现一个修改字符串内容的循环,但是我似乎无法将修改后的字节存储回内存。 使用GDB并在不同的点上断开显示,在STRB指令出现之前,所有注册表值都能正常工作。然后它因为未知的原因崩溃了。 循环应按相反顺序将所有字节递减1 .text .global _start _start: /* Thumb mode */ .code 32 add r6, pc, #1 bx r6 .
.text
.global _start
_start:
/* Thumb mode */
.code 32
add r6, pc, #1
bx r6
.code 16
mov r4, #6
mov r0, pc
add r0, #16
loop:
/*load, modify, store*/
ldrb r3, [r0]
sub r3, #1
strb r3, [r0] /*THIS IS BROKEN*/
sub r0, #1
sub r4, r4, #1
bne loop
bx lr
.data
string:
asciz "HiThere"
STRB指令似乎使程序崩溃,我正在使用一本旧书学习,我是否遗漏了一些明显的东西
编辑:是的,我知道这不是加载r0的最佳方式,但它可以工作……我想它将来可能会使用标签。
EDIT2:对不起,我知道我的问题写得不好,为了清楚起见,我加入了更多的代码。在gdb中单步执行时仍然会在STRB上崩溃。编辑:不是增加r0,而是减少它。因此,您不是在字符串中滚动,而是直接向上滚动到代码中,用小于一个字节的值覆盖指令。一旦覆盖strb指令,就会发生SIGILL 替换
sub r0, #1
与
PREVIOUS:我看到r0在代码部分中被初始化为一个内存位置,在pc之前。这是一个可写内存块吗?我不太确定 将字符串放在数据部分
编辑:还有一件事;您的循环没有退出条件。除非被告知,否则SUB不会设置标志;因此,替换
sub r4, r4, #1
与
编辑:不是增加r0,而是减少它。因此,您不是在字符串中滚动,而是直接向上滚动到代码中,用小于一个字节的值覆盖指令。一旦覆盖strb指令,就会发生SIGILL 替换
sub r0, #1
与
PREVIOUS:我看到r0在代码部分中被初始化为一个内存位置,在pc之前。这是一个可写内存块吗?我不太确定 将字符串放在数据部分
编辑:还有一件事;您的循环没有退出条件。除非被告知,否则SUB不会设置标志;因此,替换
sub r4, r4, #1
与
编辑:不是增加r0,而是减少它。因此,您不是在字符串中滚动,而是直接向上滚动到代码中,用小于一个字节的值覆盖指令。一旦覆盖strb指令,就会发生SIGILL 替换
sub r0, #1
与
PREVIOUS:我看到r0在代码部分中被初始化为一个内存位置,在pc之前。这是一个可写内存块吗?我不太确定 将字符串放在数据部分
编辑:还有一件事;您的循环没有退出条件。除非被告知,否则SUB不会设置标志;因此,替换
sub r4, r4, #1
与
编辑:不是增加r0,而是减少它。因此,您不是在字符串中滚动,而是直接向上滚动到代码中,用小于一个字节的值覆盖指令。一旦覆盖strb指令,就会发生SIGILL 替换
sub r0, #1
与
PREVIOUS:我看到r0在代码部分中被初始化为一个内存位置,在pc之前。这是一个可写内存块吗?我不太确定 将字符串放在数据部分
编辑:还有一件事;您的循环没有退出条件。除非被告知,否则SUB不会设置标志;因此,替换
sub r4, r4, #1
与
你从字符串的后端开始,然后向后走?是什么让你认为strb是问题所在?是否有代码没有显示在那里,例如在bne之后,程序/函数的结尾代码在哪里?如果这就是所有的代码,那么你在以代码的形式执行“Heree”时就崩溃了。你是裸机还是在linux中运行这些代码?如果你能记录一个地址,只要没有适当的保护机制,你就可以记录它(并不意味着它能工作,例如,如果它是在rom中,它不是在raspberry pi上,而是在一般情况下)例如,如果这都是.text,并且是某个linux二进制文件的一部分,其中.text可能被认为是只读的,并在mmu中以这种方式断言。这将使每条指令的大小为2字节,那么在计算字符串地址时,您是如何得到偏移量的
28
的?您从字符串的后端开始,然后返回?是什么让您认为strb是问题所在?是否有代码没有显示在那里,例如,在bne之后,结束程序/函数的代码在哪里?如果这就是所有的代码,那么你在以代码的形式执行“Heree”时就崩溃了。你是裸机还是在linux中运行这些代码?如果你能记录一个地址,只要没有适当的保护机制,你就可以记录它(并不意味着它能工作,例如,如果它是在rom中,它不是在raspberry pi上,而是在一般情况下)例如,如果这都是.text,并且是某个linux二进制文件的一部分,其中.text可能被认为是只读的,并在mmu中以这种方式断言。这将使每条指令的大小为2字节,那么在计算字符串地址时,您是如何得到偏移量的28
的?您从字符串的后端开始,然后返回?是什么让您认为strb是问题所在?是否有代码没有显示在那里,例如,在bne之后,结束程序/函数的代码在哪里?如果这就是所有的代码,那么你在以代码的形式执行“Heree”时就崩溃了。你是裸机还是在linux中运行这些代码?如果你能记录一个地址,只要没有适当的保护机制,你就可以记录它(并不意味着它能工作,例如,如果它是在rom中,它不是在raspberry pi上,而是在一般情况下)例如,如果这都是.text,并且是某个linux二进制文件的一部分,其中.text可能被认为是只读的,并在mmu中以这种方式断言。这将使每一条指令的长度为2字节