I have the following question here
I need to understand the following MIPS disassembling code:
.text:00489060 la $v0, 0x4D0000
.text:00489064 la $v0, 0x4D0000
.text:00489068 addiu $v1, $v0, (aBig5 - 0x4D0000) # "BIG-5"
.text:0048906C lw $v0, (aBig5 - 0x4D0000)($v0) # "BIG-5"
.text:00489070 lbu $a0, (aBig5+5 - 0x4D6A68)($v1)
.text:00489074 lbu $v1, (aBig5+4 - 0x4D6A68)($v1)
.text:00489078 swl $v0, 0($s1)
.text:0048907C swr $v0, 3($s1)
.text:00489080 sb $a0, 5($s1)
.text:00489084 b loc_48A190
.text:00489088 sb $v1, 4($s1)
.text:0048908C # ---------------------------------------------------------------------------
.text:0048908C
.text:0048908C loc_48908C: # CODE XREF: cgiGetVar+B8j
.text:0048908C lw $v1, (dword_4D6A5C - 0x4D0000)($v0) #"ISO-"
.text:00489090 addiu $v0, (dword_4D6A5C - 0x4D0000)
.text:00489094 lw $a0, (dword_4D6A60 - 0x4D6A5C)($v0) #"8859"
.text:00489098 swl $v1, 0($s1)
.text:0048909C lbu $a1, (byte_4D6A66 - 0x4D6A5C)($v0) # zero byte
.text:004890A0 lbu $a2, (byte_4D6A64 - 0x4D6A5C)($v0) # "-"
.text:004890A4 lbu $v0, (byte_4D6A65 - 0x4D6A5C)($v0) # "1"
.text:004890A8 swr $v1, 3($s1)
.text:004890AC swl $a0, 4($s1)
.text:004890B0 swr $a0, 7($s1)
.text:004890B4 sb $a1, 0xA($s1)
.text:004890B8 sb $a2, 8($s1)
.text:004890BC b loc_48A190
.text:004890C0 sb $v0, 9($s1)
.text:004890C4 #
The task I need to solve is, to change Web Language ID from BIG-5 to ISO-8859-5 in my router firmware manager (without sources :) ) So ISO-8859-5 is 5 letters longer then BIG-5. I've moved the right hand (of BIG-5) text block in .rodata section )here is hex fragment:
4d6a50: 68746d6c 63686172 73657400 49534f2d htmlcharset.ISO-
4d6a60: 38383539 2d310000 4249472d 35000000 8859-1..BIG-5...
4d6a70: 53757043 484c616e 67000000 636f6e6e SupCHLang...conn
& changed the pointer in .text section. However when I run the program it loads just 6 bytes (I see "ISO-88" instead of (ISO-8859-5) in HTML-code page of router. So I guess I have to find where is the number of developing bytes is fixed and change it. Could somebody comments this code. Thanks a lot :)
The number of bytes is not specified. It just loads a word and two bytes and that's it:
; load one word (4 bytes) into v0
lw $v0, (aBig5 - 0x4D0000)($v0)
; load one byte into a0
lbu $a0, (aBig5+5 - 0x4D6A68)($v1)
; load one byte into v1
lbu $v1, (aBig5+4 - 0x4D6A68)($v1)
; store left part of the word from v0
swl $v0, 0($s1)
; store right part of the word from v0
swr $v0, 3($s1)
; store byte from a0
sb $a0, 5($s1)
; store byte from v1
sb $v1, 4($s1)
So it's basically fixed for a 5-char string and a longer one won't work without patching the code. You might be able to patch it for a 7-char one (8 bytes) by loading words and replacing the two sb
by swl
and swr
. Another option, if you are certain that s1
is aligned, is to load three words (12 bytes) and store the latter two using just sw
instead of swl/swr pair.