Decoding and Understanding Assembly Code, Registers, Interrupts, ANSI and ANSI C

    82          phase_2(input);
(gdb) disas phase_2
Dump of assembler code for function phase_2:
0x000000000040106b <phase_2+0>: push   %rbp
0x000000000040106c <phase_2+1>: push   %rbx
0x000000000040106d <phase_2+2>: sub    $0x28,%rsp
0x0000000000401071 <phase_2+6>: mov    %rsp,%rsi
0x0000000000401074 <phase_2+9>: callq  0x401457 <read_six_numbers>
0x0000000000401079 <phase_2+14>:        cmpl   $0x0,(%rsp)
0x000000000040107d <phase_2+18>:        jne    0x401086     <phase_2+27>
0x000000000040107f <phase_2+20>:        cmpl   $0x1,0x4(%rsp)
0x0000000000401084 <phase_2+25>:        je     0x40108b <phase_2+32>
0x0000000000401086 <phase_2+27>:        callq  0x401421 <explode_bomb>

0x000000000040108b <phase_2+32>:        lea    0x8(%rsp),%rbx
0x0000000000401090 <phase_2+37>:        lea    0x18(%rsp),%rbp
0x0000000000401095 <phase_2+42>:        mov    -0x8(%rbx),%eax
0x0000000000401098 <phase_2+45>:        add    -0x4(%rbx),%eax
0x000000000040109b <phase_2+48>:        cmp    %eax,(%rbx)
0x000000000040109d <phase_2+50>:        je     0x4010a4 <phase_2+57>
0x000000000040109f <phase_2+52>:        callq  0x401421 <explode_bomb>

0x00000000004010a4 <phase_2+57>:        add    $0x4,%rbx
0x00000000004010a8 <phase_2+61>:        cmp    %rbp,%rbx
0x00000000004010ab <phase_2+64>:        jne    0x401095 <phase_2+42>

0x00000000004010ad <phase_2+66>:        add    $0x28,%rsp
0x00000000004010b1 <phase_2+70>:        pop    %rbx
0x00000000004010b2 <phase_2+71>:        pop    %rbp
0x00000000004010b3 <phase_2+72>:        retq   

Here is a C equivalent of phase2:

int t[6];
read_six_numbers (t);
if ((t[0] != 0) || (t[1] != 1)) {

for (int i = 2; i < 6; i++) {
        if (t[i] != t[i - 2] + t[i - 1]) {

So the password is 0, 1, 1, 2, 3, 5.

How did I do this ? By gradually replacing the assembly with C.

You’ll note that the stack pointer (rsp) never changes. You can see the stack as an array t of 32 bits numbers. That is each time you move by 4 bytes you move to the next element. i.e. 0(%rsp), 4(%rsp), … are equivalent to t[0], t[1], …

I’ll show you a possible gradual transformation of the bit you have trouble with:

                lea    0x8(%rsp),%rbx
                lea    0x18(%rsp),%rbp --------------> (0x18 is 24 in DECIMAL)
<phase_2+42>:   mov    -0x8(%rbx),%eax
                add    -0x4(%rbx),%eax
                cmp    %eax,(%rbx) -------------------> condition compare
                je     <phase_2+57>
                callq  explode_bomb
<phase_2+57>:   add    $0x4,%rbx
                cmp    %rbp,%rbx
                jne    phase_2+42
                    rbx = rsp + 8;
                    rbp = rsp + 24; --------------> (Ox18 is 24 in DECIMAL)
<phase_2+42>:       eax = [rbx - 8];
                    eax += [rbx - 4];
                    if (eax == [rbx]) goto <phase_2+57>; -----> Condition
<phase_2+57>:       rbx += 4;
                    if (rbx != rbp) goto phase_2+42;
rbx = rsp + 8;
rbp = rsp + 24;
do {
    eax = [rbx - 8] + [rbx - 4];
        if (eax != [rbx]) {
        rbx += 4;
} while (rbx != rbp);
rbx = 8;
do {
    eax = [rsp + rbx - 8] + [rsp + rbx - 4];
        if (eax != [rsp + rbx]) {
        rbx += 4;
} while (rbx < 24);
i = 2;
do {
    eax = t[i - 2] + t[i - 1];
        if (eax != t[i]) {
        i += 1;
} while (i < 6);
for (int i = 2; i < 6; i++) {
    if (t[i] != t[i - 2] + t[i - 1]) {

If you take the time to understand these transformations you’ll be able to transform and understand any piece of assembly.




x86 assembly language has two main syntax branches: Intel syntax, originally used for documentation of the x86 platform, and AT&T syntax.[1] Intel syntax is dominant in the MS-DOS and Windows world, and AT&T syntax is dominant in the Unix world, since Unix was created at AT&T Bell Labs.[2] Here is a summary of the main differences between Intel syntax and AT&T syntax:

AT&T Intel
Parameter order Source before the destination.

mov $5, %eax
Destination before source.

mov eax, 5
Parameter size Mnemonics are suffixed with a letter indicating the size of the operands: q for qword, l for long (dword), w for word, and bfor byte.[1]

addl $4, %esp
Derived from the name of the register that is used (e.g. rax, eax, ax, al imply q, l, w, b, respectively).

add esp, 4
Sigils Immediate values prefixed with a “$”, registers prefixed with a “%”.[1] The assembler automatically detects the type of symbols; i.e., if they are registers, constants or something else.
Effectiveaddresses Use general syntax of DISP(BASE,INDEX,SCALE). Example:

movl mem_location(%ebx,%ecx,4), %eax
Use variables, and need to be in square brackets; additionally, size keywords likebyte, word, or dword have to be used if the size cannot be determined from the operands.[1] Example:

mov eax, [ebx + ecx*4 + mem_location]

Many x86 assemblers use Intel syntax including MASM, TASM, NASM, FASM and YASM. GAS has supported both syntaxes since version 2.10 via the .intel_syntaxdirective.





x86 Registers

The main tools to write programs in x86 assembly are the processor registers. The registers are like variables built in the processor. Using registers instead of memory to store values makes the process faster and cleaner. The problem with the x86 serie of processors is that there are few registers to use. This section describes the main use of each register and ways to use them. That in note that the rules described here are more suggestions than strict rules. Some operations need absolutely some kind of registers but most of the you can use any of the freely.

Here is a list of the available registers on the 386 and higher processors. This list shows the 32 bit registers. Most of the can be broken down to 16 or even 8 bits register.

General registers

Segment registers

Index and pointers


General registers
As the title says, general register are the one we use most of the time Most of the instructions perform on these registers. They all can be broken down into 16 and 8 bit registers.

64 bits : RAX RBX RCX RDX
32 bits : EAX EBX ECX EDX
16 bits : AX BX CX DX
 8 bits : AH AL BH BL CH CL DH DL

The “H” and “L” suffix on the 8 bit registers stand for high byte and low byte. With this out of the way, let’s see their individual main use

EAX,AX,AH,AL : Called the Accumulator register. 
               It is used for I/O port access, arithmetic, interrupt calls,

EBX,BX,BH,BL : Called the Base register
               It is used as a base pointer for memory access
               Gets some interrupt return values

ECX,CX,CH,CL : Called the Counter register
               It is used as a loop counter and for shifts
               Gets some interrupt values

EDX,DX,DH,DL : Called the Data register
               It is used for I/O port access, arithmetic, some interrupt 

Segment registers

Segment registers hold the segment address of various items. They are only available in 16 values. They can only be set by a general register or special instructions. Some of them are critical for the good execution of the program and you might want to consider playing with them when you’ll be ready for multi-segment programming

CS         : Holds the Code segment in which your program runs.
             Changing its value might make the computer hang.

DS         : Holds the Data segment that your program accesses.
             Changing its value might give erronous data.

ES,FS,GS   : These are extra segment registers available for
             far pointer addressing like video memory and such.

SS         : Holds the Stack segment your program uses.
             Sometimes has the same value as DS.
             Changing its value can give unpredictable results,
             mostly data related.

Indexes and pointers

Indexes and pointer and the offset part of and address. They have various uses but each register has a specific function. They some time used with a segment register to point to far address (in a 1Mb range). The register with an “E” prefix can only be used in protected mode.

ES:EDI EDI DI : Destination index register
                Used for string, memory array copying and setting and
                for far pointer addressing with ES

DS:ESI EDI SI : Source index register
                Used for string and memory array copying

SS:EBP EBP BP : Stack Base pointer register
                Holds the base address of the stack
SS:ESP ESP SP : Stack pointer register
                Holds the top address of the stack

CS:EIP EIP IP : Index Pointer
                Holds the offset of the next instruction
                It can only be read 

The EFLAGS register

The EFLAGS register hold the state of the processor. It is modified by many intructions and is used for comparing some parameters, conditional loops and conditionnal jumps. Each bit holds the state of specific parameter of the last instruction. Here is a listing :

Bit   Label    Desciption
0      CF      Carry flag
2      PF      Parity flag
4      AF      Auxiliary carry flag
6      ZF      Zero flag
7      SF      Sign flag
8      TF      Trap flag
9      IF      Interrupt enable flag
10     DF      Direction flag
11     OF      Overflow flag
12-13  IOPL    I/O Priviledge level
14     NT      Nested task flag
16     RF      Resume flag
17     VM      Virtual 8086 mode flag
18     AC      Alignment check flag (486+)
19     VIF     Virutal interrupt flag
20     VIP     Virtual interrupt pending flag
21     ID      ID flag

Those that are not listed are reserved by Intel.

Undocumented registers

There are registers on the 80386 and higher processors that are not well documented by Intel. These are divided in control registers, debug registers, test registers and protected mode segmentation registers. As far as I know, the control registers, along with the segmentation registers, are used in protected mode programming, all of these registers are available on 80386 and higher processors except the test registers that have been removed on the pentium. Control registers are CR0 to CR4, Debug registers are DR0 to DR7, test registers are TR3 to TR7 and the protected mode segmentation registers are GDTR (Global Descriptor Table Register), IDTR (Interrupt Descriptor Table Register), LDTR (Local DTR), and TR.



64-bit register Lower 32 bits Lower 16 bits Lower 8 bits
rax eax ax al
rbx ebx bx bl
rcx ecx cx cl
rdx edx dx dl
rsi esi si sil
rdi edi di dil
rbp ebp bp bpl
rsp esp sp spl
r8 r8d r8w r8b
r9 r9d r9w r9b
r10 r10d r10w r10b
r11 r11d r11w r11b
r12 r12d r12w r12b
r13 r13d r13w r13b
r14 r14d r14w r14b
r15 r15d r15w r15b



Interrupt vector Description
05h Executed when Shift-Print screen is pressed, as well as when the BOUND instruction detects a bound failure.
10h Video Services

AH Description
00h Set Video Mode
01h Set Cursor Shape
02h Set Cursor Position
03h Get Cursor Position And Shape
04h Get Light Pen Position
05h Set Display Page
06h Clear/Scroll Screen Up
07h Clear/Scroll Screen Down
08h Read Character and Attribute at Cursor
09h Write Character and Attribute at Cursor
0Ah Write Character at Cursor
0Bh Set Border Color
0Ch Write Graphics Pixel
0Dh Read Graphics Pixel
0Eh Write Character in TTY Mode
0Fh Get Video Mode
10h Set Palette Registers (EGA, VGA, SVGA)
11h Character Generator (EGA, VGA, SVGA)
12h Alternate Select Functions (EGA, VGA, SVGA)
13h Write String
1Ah Get or Set Display Combination Code (VGA, SVGA)
1Bh Get Functionality Information (VGA, SVGA)
1Ch Save or Restore Video State (VGA, SVGA)
4Fh VESA BIOS Extension Functions (SVGA)
11h Returns equipment list
12h Return conventional memory size
13h Low Level Disk Services

AH Description
00h Reset Disk Drives
01h Check Drive Status
02h Read Sectors
03h Write Sectors
04h Verify Sectors
05h Format Track
08h Get Drive Parameters
09h Init Fixed Drive Parameters
0Ch Seek To Specified Track
0Dh Reset Fixed Disk Controller
15h Get Drive Type
16h Get Floppy Drive Media Change Status
17h Set Disk Type
18h Set Floppy Drive Media Type
41h Extended Disk Drive (EDD) Installation Check
42h Extended Read Sectors
43h Extended Write Sectors
44h Extended Verify Sectors
45h Lock/Unlock Drive
46h Eject Media
47h Extended Seek
48h Extended Get Drive Parameters
49h Extended Get Media Change Status
4Eh Extended Set Hardware Configuration
14h Serial port services

AH Description
00h Serial Port Initialization
01h Transmit Character
02h Receive Character
03h Status
15h Miscellaneous system services

AH AL Description
00h Turn on cassette drive motor
01h Turn off cassette drive motor
02h Read data blocks from cassette
03h Write data blocks to cassette
4Fh Keyboard Intercept
83h Event Wait
84h Read Joystick
85h Sysreq Key Callout
86h Wait
87h Move Block
88h Get Extended Memory Size
89h Switch to Protected Mode
C0h Get System Parameters
C1h Get Extended BIOS Data Area Segment
C2h Pointing Device Functions
C3h Watchdog Timer Functions – PS/2 systems only
C4h Programmable Option Select – MCA bus PS/2 systems only
D8h EISA System Functions – EISA bus systems only
E8h 01h Get Extended Memory Size (Newer function, since 1994). Gives results for memory size above 64 Mb.
E8h 20h Query System Address Map. The information returned from E820 supersedes what is returned from the older AX=E801h andAH=88h interfaces.
16h Keyboard services

AH Description
00h Read Character
01h Read Input Status
02h Read Keyboard Shift Status
05h Store Keystroke in Keyboard Buffer
10h Read Character Extended
11h Read Input Status Extended
12h Read Keyboard Shift Status Extended
17h Printer services

AH Description
00h Print Character to Printer
01h Initialize Printer
02h Check Printer Status
18h Execute Cassette BASIC: Very early true IBM computers contain Microsoft Cassette BASIC in the ROM, to be started by this routine in the event of a failure to boot from disk (called by the BIOS). On virtually all clones and later models in the PC line from IBM, which lack BASIC in ROM, this interrupt typically displays a message such as “No ROM BASIC” and halts.
19h After POST this interrupt is used by BIOS to load the operating system. A program can call this interrupt to reboot the computer (but must ensure that hardware interrupts or DMA operations will not cause the system to hang or crash during either the reinitialization of the system by BIOS or the boot process).
1Ah Real Time Clock Services

AH Description
00h Read RTC
01h Set RTC
02h Read RTC Time
03h Set RTC Time
04h Read RTC Date
05h Set RTC Date
06h Set RTC Alarm
07h Reset RTC Alarm
1Ah PCI Services – implemented by BIOSes supporting PCI 2.0 or later

AX Description
B101h PCI Installation Check
B102h Find PCI Device
B103h Find PCI Class Code
B106h PCI Bus-Specific Operations
B108h Read Configuration Byte
B109h Read Configuration Word
B10Ah Read Configuration Dword
B10Bh Write Configuration Byte
B10Ch Write Configuration Word
B10Dh Write Configuration Dword
B10Eh Get IRQ Routine Information
1Bh Ctrl-Break handler – called by INT 09 when Ctrl-Break has been pressed
1Ch Timer tick handler – called by INT 08
1Dh Not to be called; simply a pointer to the VPT (Video Parameter Table), which contains data on video modes
1Eh Not to be called; simply a pointer to the DPT (Diskette Parameter Table), containing a variety of information concerning the diskette drives
1Fh Not to be called; simply a pointer to the VGCT (Video Graphics Character Table), which contains the data for ASCII characters 80h to FFh
41h Address pointer: FDPT = Fixed Disk Parameter Table (1st hard drive)
46h Address pointer: FDPT = Fixed Disk Parameter Table (2nd hard drive)
4Ah Called by RTC for alarm



🙂 have fun in reading…

This entry was posted in ASSEMBLY LANGUAGE. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s