5

I just started learning about assembly language in Kali Linux in VMware. I have a Ryzen 5 CPU. In the below code snippet, I have a few things I don't understand.

  • What is the meaning of lea rax, [rip ± 0xeb3] at <main + 17>? I understand what lea does, but what is the meaning of ±?
  • And what is the purpose of RDI after getting updated?
(gdb) list
1       #include<stdio.h>
2
3       int main(){
4               int i;
5               for(i = 0 ; i < 10 ; i++){
6                       printf("Hello World!\n");
7               }
8               return 0;
9       }
(gdb) disassemble main
Dump of assembler code for function main:
   0x0000000000001139 <+0>:     push   rbp
   0x000000000000113a <+1>:     mov    rbp,rsp
   0x000000000000113d <+4>:     sub    rsp,0x10
   0x0000000000001141 <+8>:     mov    DWORD PTR [rbp-0x4],0x0
   0x0000000000001148 <+15>:    jmp    0x115d <main+36>
   0x000000000000114a <+17>:    lea    rax,[rip±0xeb3]        # 0x2004
   0x0000000000001151 <+24>:    mov    rdi,rax
   0x0000000000001154 <+27>:    call   0x1030 <puts@plt>
   0x0000000000001159 <+32>:    add    DWORD PTR [rbp-0x4],0x1
   0x000000000000115d <+36>:    cmp    DWORD PTR [rbp-0x4],0x9
   0x0000000000001161 <+40>:    jle    0x114a <main+17>
   0x0000000000001163 <+42>:    mov    eax,0x0
   0x0000000000001168 <+47>:    leave  
   0x0000000000001169 <+48>:    ret    
End of assembler dump.
(gdb) 

Edit:

gdb -v        
GNU gdb (Debian 12.1-3) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • Could be useful to show the output of `gdb -v` – Marco Bonelli Aug 25 '22 at 18:12
  • I would suspect that it is actually supposed to be "-" but that it is being printed as "+ -" and then getting transformed to ± for some reason. – SoronelHaetir Aug 25 '22 at 18:52
  • @SoronelHaetir `0x1151 + 0xeb3 = 0x2004` though – Marco Bonelli Aug 25 '22 at 19:16
  • What shell and terminal are you using? Give us more details about your environment. AFAICT that symbol simply is not to be found anywhere in GDB/libopcodes code. – Marco Bonelli Aug 25 '22 at 19:16
  • @MarcoBonelli I was using a normal terminal in Kali Linux, not as the root user, but the user was privileged. Can you please mention what details do you need about the environment? – Karan Tejas Aug 25 '22 at 20:09
  • 7
    I can reproduce this. It's not a plus-minus, it's an underlined plus. Possibly due to a wrong color escape sequence. – Margaret Bloom Aug 25 '22 at 22:52
  • 10
    Ok, found the bug. gdb 12.1 [uses Python (!!!) to colorize its output](https://sourceware.org/gdb/onlinedocs/gdb/Output-Styling.html). Specifically, it uses the Pygments packages. Which handles x64 code badly, [here's a test case](https://pastebin.com/dgvSRYH4). The (yet to be released) next version uses and entirely different coloring code, where each disassembler function can introduce style markers in its output and the `disassemble` command (`gdb/disassemble.c`) translate those markers into terminal escapes. – Margaret Bloom Aug 26 '22 at 00:20
  • 1
    OK so it means + right? Thanks for checking out. – Karan Tejas Aug 26 '22 at 06:08
  • 4
    @KaranTejas you can do `set style disassembler enabled off` to disable the disassembler styling, this should fix the formatting issues. – Andrew Aug 26 '22 at 08:23
  • 2
    @MargaretBloom: You could post that as an answer. BTW, on my Arch Linux system, in Konsole, your pastebin test-case prints an underlined `+` which looks confusing at first, but once you know to look for it, is clearly a `+` with an underline of the whole cell. And it copy/pastes as `+`, not `±` – Peter Cordes Aug 27 '22 at 11:04
  • @PeterCordes That's how I found it was a plus and not a plus-minus: by copy-pasting it to remove any formatting. Then spent an hour trying to figure out what is wrong with the coloring code only to realize (later) that I was looking at GDB 13 :) I'll post an answer so this can be marked as answered. – Margaret Bloom Aug 28 '22 at 15:29
  • @MargaretBloom: I assume the OP had copy/pasted from their terminal into the question, where the code blocks have `±`. Pretty misleading [mcve] if actual GDB isn't outputting that character on their terminal, without saying anything about manually editing to make it look like what they see. Maybe some terminal emulator copy/pastes an underlined `+` as `±`, or some other innocent explanation. Hope that didn't cost you too much extra time when tracking this down. – Peter Cordes Aug 28 '22 at 20:48

1 Answers1

4

It's not a plus-minus (±, Unicode point 0x00b1), it's an underlined plus.
If you copy-paste it, you get only a plus (+).

GDB 12.1 uses Python to colorize each line of its disassembler output. Specifically, it uses the Pygments packages, which, at the current version 2.11.2, handle x64 code badly, here's a test case:

from pygments import formatters, lexers, highlight
 
def colorize_disasm(content, gdbarch):
    # Don't want any errors.
    try:
        lexer = lexers.get_lexer_by_name("asm")
        formatter = formatters.TerminalFormatter()
        return highlight(content, lexer, formatter).rstrip().encode()
    except:
        return None
 
 
print(colorize_disasm("lea [rip+0x211]  #test", None).decode())

Wrong Pygments output for RIP-relative operands

The (yet to be released) next version uses an entirely different coloring code, where each disassembler function can introduce style markers in its output and the disassemble command (see gdb/disassemble.c) translates those markers into terminal escapes.

Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124