In ARM assembly, what is the difference between
ldr r4, =0x44454433
and
ldr r4, #0x44454433
?
the first one ldr r4, =0x44454433 is a valid pseudo instuction
the second one is invalid
btw the syntax is not for a real instruction but an alias a pseudo instruction
the assembler creates proper instruction with respect to immediate values
most of these questions can be answered by assembling a single instruction and
disassembling it
you can use armasm from msvc
or you can use keystone with python or
use the innumerable online assembler disassembler sites
import sys
from keystone import *
instruction = raw_input("Enter your arm instruction : ")
print instruction
ks = Ks(KS_ARCH_ARM,KS_MODE_ARM|KS_MODE_THUMB)
blah = ks.asm(instruction)
for i in blah[0]:
print "%02x " % i,
print "\n"
executed the script to get
:\>python asmarm.py
Enter your arm instruction : ldr r4,=0x44455533
ldr r4,=0x44455533
00 4c 00 bf 33 55 45 44
on the other hand if you try assembling the second instruction it will raise an error unexpected token
:\>python asmarm.py
Enter your arm instruction : ldr r4,=#0x44554533
ldr r4,=#0x44554533
Traceback (most recent call last):
File "asmarm.py", line 7, in <module>
blah = ks.asm(instruction)
File "c:\python27\lib\site-packages\keystone\keystone.py", line 198, in asm
raise KsError(errno, stat_count.value)
keystone.keystone.KsError: Unknown token in expression (KS_ERR_ASM_EXPR_TOKEN)
or you can use capstone to disassemble a hex byte sequence
as below
import sys
from capstone import *
import binascii
inp = binascii.unhexlify( ''.join(sys.argv[1].split()))
cs = Cs(CS_ARCH_ARM , CS_MODE_THUMB)
cs.Detail = True
dis = cs.disasm( inp, int(sys.argv[2],16))
for i in dis:
print("0x%x:\t" % i.address),
print(binascii.hexlify(i.bytes)),
print("\t%s\t%s" %(i.mnemonic, i.op_str))
executing the script
:\>discap.py "00 4c 00 bf 33 55 45 44" 0x440000
0x440000: 004c ldr r4, [pc, #0]
0x440002: 00bf nop
0x440004: 3355 strb r3, [r6, r4]
0x440006: 4544 add r5, r8
if you use msvc route you need to open a vsdev cmdprompt with a proper architecxture and simple use armasm with an input file as below
set correct arch and host
C:\>cat bld.bat
pushd ..
call "C:\Program Files\Microsoft Visual Studio\2017\Community\Common7\Tools\vsdevcmd.bat" -arch=arm -host_arch=x86
src file contents
C:\>cat myasm.asm
AREA .text, CODE, ARM
test PROC
ldr r4,=0x44455533
ENDP
END
execute and open a msvc arm devprompt
C:\>bld.bat
C:\>pushd ..
C:\>call "C:\Program Files\Microsoft Visual Studio\2017\Community\Common7\Tools\vsdevcmd.bat" -arch=arm -host_arch=x86
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.6.1
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
C:\>popd
assemble the input file
C:\>armasm myasm.asm
Microsoft (R) ARM Macro Assembler Version 14.13.26128.0
Copyright (C) Microsoft Corporation. All rights reserved.
disassemble the obj file
C:\>dumpbin /disasm myasm.obj
Microsoft (R) COFF/PE Dumper Version 14.13.26128.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file myasm.obj
File Type: COFF OBJECT
test:
00000000: 4C00 ldr r4,00000004
00000002: 0000 movs r0,r0
00000004: 5533 strb r3,[r6,r4]
00000006: 4445 add r5,r5,r8
Summary
60 .debug$S
8 .text
C:\>
Although this is be a simple LMGTFY question, I'm going to answer since it took me some time to find it.
Assuming it's 32bit ARM all the opcodes are 4 bytes long so this poses a question how one can include a 32bit value in the opcode if opcode with such big data would not fit in 4 bytes.
ldr r4, =0x44454433
is a pseudo-instruction.
The LDR Rd,=const pseudo-instruction generates the most efficient single instruction to load any 32-bit number. - page 6-111
The other const #0x44454433
is just a const value, but with this form (having 32 bit value in it and just the value) seems invalid (not an expert on ARM).