In ARM assembly, what is the difference between

ldr r4, =0x44454433


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

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.Detail = True
dis = cs.disasm( inp,  int(sys.argv[2],16))
for i in dis:
    print("0x%x:\t" % i.address),
    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

execute and open a msvc arm devprompt


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

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


  00000000: 4C00      ldr         r4,00000004
  00000002: 0000      movs        r0,r0
  00000004: 5533      strb        r3,[r6,r4]
  00000006: 4445      add         r5,r5,r8


          60 .debug$S
           8 .text

| improve this answer | |
  • Exactly what I was looking for. Thanks for showing capstone and keystone. – not2qubit Oct 17 '18 at 22:03
  • What pip package is keystone? – not2qubit Oct 17 '18 at 22:22

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).

| improve this answer | |
  • Correct. It just a convenient shorthand notation for "load a large constant from a nearby address". It is not an instruction in itself; a disassembler may choose to show it that way, but the actual code is something different. – usr2564301 Mar 25 '18 at 11:07
  • 1
    If you're curious about what immediate values can be represented in the instruction directly, I thought this was a nice resource: alisdair.mcdiarmid.org/arm-immediate-value-encoding – Brendan Dolan-Gavitt Mar 25 '18 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.