How to print register values in GDB? - gdb

How do I print the value of %eax and %ebp?
(gdb) p $eax
$1 = void

info registers shows all the registers; info registers eax shows just the register eax. The command can be abbreviated as i r

If you're trying to print a specific register in GDB, you have to omit the % sign. For example,
info registers eip
If your executable is 64 bit, the registers start with r. Starting them with e is not valid.
info registers rip
Those can be abbreviated to:
i r rip

There is also:
info all-registers
Then you can get the register name you are interested in -- very useful for finding platform-specific registers (like NEON Q... on ARM).

If only want check it once, info registers show registers.
If only want watch one register, for example, display $esp continue display esp registers in gdb command line.
If want watch all registers, layout regs continue show registers, with TUI mode.

Gdb commands:
i r <register_name>: print a single register, e.g i r rax, i r eax
i r <register_name_1> <register_name_2> ...: print multiple registers, e.g i r rdi rsi,
i r: print all register except floating point & vector register (xmm, ymm, zmm).
i r a: print all register, include floating point & vector register (xmm, ymm, zmm).
i r f: print all FPU floating registers (st0-7 and a few other f*)
Other register groups besides a (all) and f (float) can be found with:
maint print reggroups
as documented at: https://sourceware.org/gdb/current/onlinedocs/gdb/Registers.html#Registers
Tips:
xmm0 ~ xmm15, are 128 bits, almost every modern machine has it, they are released in 1999.
ymm0 ~ ymm15, are 256 bits, new machine usually have it, they are released in 2011.
zmm0 ~ zmm31, are 512 bits, normal pc probably don't have it (as the year 2016), they are released in 2013, and mainly used in servers so far.
Only one serial of xmm / ymm / zmm will be shown, because they are the same registers in different mode. On my machine ymm is shown.

p $eax works as of GDB 7.7.1
Tested as of GDB 7.7.1, the command you've tried works:
set $eax = 0
p $eax
# $1 = 0
set $eax = 1
p $eax
# $2 = 1
This syntax can also be used to select between different union members e.g. for ARM floating point registers that can be either floating point or integers:
p $s0.f
p $s0.u
From the docs:
Any name preceded by ‘$’ can be used for a convenience variable, unless it is one of the predefined machine-specific register names.
and:
You can refer to machine register contents, in expressions, as variables with names starting with ‘$’. The names of registers are different for each machine; use info registers to see the names used on your machine.
But I haven't had much luck with control registers so far: OSDev 2012 http://f.osdev.org/viewtopic.php?f=1&t=25968 || 2005 feature request https://www.sourceware.org/ml/gdb/2005-03/msg00158.html || alt.lang.asm 2013 https://groups.google.com/forum/#!topic/alt.lang.asm/JC7YS3Wu31I
ARM floating point registers
See: https://reverseengineering.stackexchange.com/questions/8992/floating-point-registers-on-arm/20623#20623

Easiest for me is:
(gdb) x/x $eax
First x stands for examine and second x is hex. You can see other formats using:
(gdb) help x
You can easily print strings with x/s $eax or return addresses with x/a $ebp+4.

Related

AWS Neoverse N1 r3p1: MOVSNE pc, lr = Illegal instruction unconditionally

On a Neoverse N1 r3p1 in a AWS t4g.nano instance, in 32-bit user mode the following pieces of code result an illegal instruction exception:
teq pc, pc
movsne pc, lr
and
teq pc, pc
ldmfdne sp!, {pc}
However from reading the current Arm Architecture Reference Manual it should work, firstly teq pc, pc should set the Z flag in 32-bit modes (and clear Z in 26-bit modes if one of PSR bits is set), the pseudo-code for MOVS states:
if ConditionPassed() then
EncodingSpecificOperations();
(shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C);
result = shifted;
if d == 15 then
if setflags then
ALUExceptionReturn(result);
else
ALUWritePC(result);
else
// else branch snipped
ALUExceptionReturn(result) is CONSTRAINED UNPREDICTABLE, but control flow shouldn't reach there.
Is my understanding wrong or is the CPU broken?
Is it safe to replace the offending instruction in an exception handler (a Linux SIGILL handler) without stopping other threads?
A complete test program for Linux:
.syntax unified
.global _start
_start:
teq pc, pc
movsne pc, lr
mov r7, #1
svc 0
The intent is to return restoring the PSR in 26-bit modes, in order to comply with an old ABI on sufficiently old hardware.

ATmega8 doesn't support JMP instruction

Now I'm writing bootloader which starts in the middle of memory, but after it finishes I need to go to the main app, thought to try jmp 0x00, however my chip doesn't support jmp, how should I start main app?
I would use RJMP:
Relative jump to an address within PC - 2K +1 and PC + 2K (words). In
the assembler, labels are used instead of relative operands.
For example:
entry:
rjmp reset
.org 512
reset:
rjmp foo
.org 3072
foo:
rjmp entry
By the way, there are several other jump instructions (RJMP, IJMP, RCALL, ICALL, CALL, RET, RETI etc.) See this relevant discussion.
Well take a look into RET instruction. It returns to previous location, so you can try:
push 0x00
push 0x00
ret
This should work because while entering into any function you push your current location, and RET makes you go back.
As far as I remember ATmege8 has 16-bit address line, but if I'm not right you may need more push 0x00
why not simply use IJMP?
set Z to 0x00 and use IJMP. may be faster than 2xpush and ret
EOR R30, R30 ; clear ZL
EOR R31, R31 ; clear ZH
IJMP ; set PC to Z
should be 4 cycles and 3 instruction words (6 Bytes program memory)

ORG alternative for C++

In assembly we use the org instruction to set the location counter to a specific location in the memory. This is particularly helpful in making Operating Systems. Here's an example boot loader (From wikibooks):
org 7C00h
jmp short Start ;Jump over the data (the 'short' keyword makes the jmp instruction smaller)
Msg: db "Hello World! "
EndMsg:
Start: mov bx, 000Fh ;Page 0, colour attribute 15 (white) for the int 10 calls below
mov cx, 1 ;We will want to write 1 character
xor dx, dx ;Start at top left corner
mov ds, dx ;Ensure ds = 0 (to let us load the message)
cld ;Ensure direction flag is cleared (for LODSB)
Print: mov si, Msg ;Loads the address of the first byte of the message, 7C02h in this case
;PC BIOS Interrupt 10 Subfunction 2 - Set cursor position
;AH = 2
Char: mov ah, 2 ;BH = page, DH = row, DL = column
int 10h
lodsb ;Load a byte of the message into AL.
;Remember that DS is 0 and SI holds the
;offset of one of the bytes of the message.
;PC BIOS Interrupt 10 Subfunction 9 - Write character and colour
;AH = 9
mov ah, 9 ;BH = page, AL = character, BL = attribute, CX = character count
int 10h
inc dl ;Advance cursor
cmp dl, 80 ;Wrap around edge of screen if necessary
jne Skip
xor dl, dl
inc dh
cmp dh, 25 ;Wrap around bottom of screen if necessary
jne Skip
xor dh, dh
Skip: cmp si, EndMsg ;If we're not at end of message,
jne Char ;continue loading characters
jmp Print ;otherwise restart from the beginning of the message
times 0200h - 2 - ($ - $$) db 0 ;Zerofill up to 510 bytes
dw 0AA55h ;Boot Sector signature
;OPTIONAL:
;To zerofill up to the size of a standard 1.44MB, 3.5" floppy disk
;times 1474560 - ($ - $$) db 0
Is it possible accomplish the task with C++? Is there any command, function etc. like org where i can change the location of the program?
No it's not possible to do in any C compiler that I know of. You can however create your own linker script that places the code/data/bss segments at specific addresses.
Just for clarity, the org directive does not load the code at the specified address, it merely informs the assembler that the code will be loaded at that address. The code shown appears to be for Nasm (or similar) - in AT&T syntax, the .org directive does something different: it pads the code to that address - similar to the times line in the Nasm code.. Nasm can do this because in -f bin mode, it "acts as it's own linker".
The important thing for the code to know is the address where Msg can be found. The jmps and jnes (and call and ret which your example doesn't have, but a compiler may generate) are relative addressing mode. We code jmp target but the bytes that are actually emitted say jmp distance_to_target (plus or minus) so the address doesn't matter.
Gas doesn't do this, it emits a linkable object file. To use ld without a linker script the command line looks something like:
ld -o boot.bin boot.o -oformat binary -T text=0x7C00
(don't quote me on that exact syntax but "something like that") If you can get a linkable object file from your (16-bit capable!) C++ compiler, you might be able to do the same.
In the case of a bootsector, the code is loaded by the BIOS (or fake BIOS) at 0x7C00 - one of the few things we can assume about the bootsector. The sane thing for a bootsector to do is not fiddle-faddle around printing a message, but to load something else. You'll need to know how to find the something else on the disk and where you want to load it to (perhaps where your C++ compiler wants to put it by default) - and jmp there. This jmp will want to be a far jmp, which does need to know the address.
I'm guessing it's going to be some butt-ugly C++!

Need information about using Inline Assembly for WinCE, ARM9

I am not very good in inline assembly, but planning to use it for optimization purpose in an Embedded project. As I don't know much of the information about it, I am in need of some help.
I am having Win CE 6.0, with ARM9, using MS Visual Studio 2005 (using MFC).
Basically, I want to make memory access faster, and do some bitwise operations.
It would be really helpful for me if I can get any online link, or some examples of using registers, variable names, pointers (some memory transfer and bitwise operations related stuff) etc for my particular environment.
EDIT after ctacke's answer:
It would be really helpful for me if there is any link or small examples to work out with .s files, specifically writing and exporting functions from .s, and steps involving in combining them with my MFC application. Any small example would do it.
Thank You.
Kind Regards,
Aftab
The ARM compilers that ship with Visual Studio (all versions) do not support inline ASM - only the x86 compilers support inline ASM. To use ASM for ARM (or SH or MIPS as well) you have to create a separate code file (typically a .s file), export functions from your ASM and call those.
EDIT
Here's a simple example (taken from here):
AREA asm_func, CODE, READONLY
; Export my_asm function location so that C compiler can find it and link
EXPORT my_asm
my_asm
;
; ARM Assembly language function to set LED1 bit to a value passed from C
; LED1 gets value (passed from C compiler in R0)
; LED1 is on GPIO port 1 bit 18
; See Chapter 9 in the LPC1768 User Manual
; for all of the GPIO register info and addresses
; Pinnames.h has the mbed modules pin port and bit connections
;
; Load GPIO Port 1 base address in register R1
LDR R1, =0x2009C020 ; 0x2009C020 = GPIO port 1 base address
; Move bit mask in register R2 for bit 18 only
MOV.W R2, #0x040000 ; 0x040000 = 1<<18 all "0"s with a "1" in bit 18
; value passed from C compiler code is in R0 - compare to a "0"
CMP R0, #0 ; value == 0 ?
; (If-Then-Else) on next two instructions using equal cond from the zero flag
ITE EQ
; STORE if EQ - clear led 1 port bit using GPIO FIOCLR register and mask
STREQ R2, [R1,#0x1C] ; if==0, clear LED1 bit
; STORE if NE - set led 1 port bit using GPIO FIOSET register and mask
STRNE R2, [R1,#0x18] ; if==1, set LED1 bit
; Return to C using link register (Branch indirect using LR - a return)
BX LR
END

GDB + Core file dump

Can some please help me to understand this:-
Below is an extract from gdb. After my program crashed, I opened the binary and core file in gdb and issued the command info frame:
(gdb) info frame
Stack level 0, frame at 0xb75f7390:
eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a
called by frame at 0xb75f73b0
source language c++.
Arglist at 0xb75f7388, args: this=0x0
Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390
Saved registers:
ebp at 0xb75f7388, eip at 0xb75f738c
What do the lines "ebp", "eip", "Locals at" and "Previous Frame's sp " mean? Please explain
This diagram from the Wikipedia article Call stack may help:
GDB's info frame corresponds to functions being called in your program at run time. From the output, we can infer this about the stack frame layout:
0xb75f7388: The 4 bytes starting here stores the old EBP value, 0xb75f73a8. The first value pushed by the function prologue of base::func()
0xb75f738c: The 4 bytes starting here stores the return address, 0x804869a. Pushed by the call instruction in the previous frame
0xb75f7390: The 4 bytes starting here stores the implicit this argument to base::func(), 0x00000000.
I'll explain the info frame output line by line:
Stack level 0, frame at 0xb75f7390:
Stack level 0 means this is the newest frame. The address after frame at is called the Canonical Frame Address (CFA). On x86, this is defined to be the value of the stack pointer (ESP) at the previous frame, before the call instruction is executed.
eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a
EIP is the x86 instruction pointer. saved eip is the return address.
If you try to look up the function that contains 0x804869a with info symbol 0x804869a, it should point inside the function calling base::func().
called by frame at 0xb75f73b0
called by shows the canonical frame address of the previous frame. We can see that the stack pointer advanced 32 bytes (0xb75f73b0 - 0xb75f7390 = 32) between the two frames.
source language c++.
Arglist at 0xb75f7388, args: this=0x0
Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390
The x86 ABI passes arguments on the stack. base::func() only has the single implicit this argument. The fact that it's 0x0 i.e. NULL bodes ill. On a side note, Arglist and Locals seem to always have the same value in info frame on x86 and x86-64.
Saved registers:
ebp at 0xb75f7388, eip at 0xb75f738c
Saved registers reflects the registers that were saved at function entry. It lists where the old register values are saved on the stack. Saved EIP is the return address so if you examine the address stored at 0xb75f738c with x/a 0xb75f738c it should give 0x804869a. The fact that EBP is listed here implies that your code probably was not compiled with -fomit-frame-pointer and has a standard function prologue:
push %ebp
movl %esp, %ebp
at the very begging of base::func() which sets up EBP to act as the frame pointer.
To analyze core file, execute:
$gdb executable core
gdb$ bt -- backtrace
or gdb$ fr 0 -- the uppermost frame in the run-time stack
gdb$ fr 1 & so on will give you the order of function calls which led to Seg Fault.
Here, gdb$info frame is providing you info about frame 0.