How to read a NASM Assembly program .lst listing file
Asked Answered
P

1

10

I wrote a NASM program and created a listing file from it using nasm -f elf -l rs.lst rs.asm. The program, which works perfectly, takes in a key input value, and outputs whether the value is a control key or printable key, and if it is a number, lowercase, or uppercase letter.

I need help understanding what I am reading in the .lst file. Are the numbers on the left addresses? Instructions? DO they represent memory? Here's the .lst.

     1                                  segment .data
        //Removed my student ID info                            
     8                                      ;Program Output Strings
     9                                  
    10 00000023 5072657373204B6579-         askForKey: db 'Press Key and Enter: ', 10   ; ;10 is the newline value
    11 0000002C 20616E6420456E7465-
    12 00000035 723A200A           
    13                                      askLen: equ $-askForKey
    14                                  
    15 00000039 436F6E74726F6C204B-         controlKey: db 'Control Key ', 10
    16 00000042 6579200A           
    17                                      controlLen: equ $-controlKey
    18                                      
    19 00000046 5072696E7461626C65-         printableKey: db 'Printable Key ', 10   
    20 0000004F 204B6579200A       
    21                                      printableLen: equ $-printableKey
    22                                  
    23 00000055 446563696D616C204B-         decimalKey: db 'Decimal Key ', 10
    24 0000005E 6579200A           
    25                                      decimalLen: equ $-decimalKey
    26                                  
    27 00000062 55707065722D636173-         upperKey: db 'Upper-case Key ', 10
    28 0000006B 65204B6579200A     
    29                                      upperLen: equ $-upperKey
    30                                  
    31 00000072 4C6F7765722D636173-         lowerKey: db 'Lower-case Key ', 10
    32 0000007B 65204B6579200A     
    33                                      lowerLen: equ $-lowerKey
    34                                      
    35 00000082 0A                          blankLine: db '', 10
    36                                      blankLen: equ $-blankLine
    37                                   
    38                                  segment .bss
    39                                  
    40 00000000 <res 00000002>              key resb 2
    41                                  
    42                                  segment .text
    43                                  
    44                                      global main
    45                                  main:
    46                                  
    47                                  
    48 00000000 B804000000                  mov eax, 4      ; system call 4
    49 00000005 BB01000000                  mov ebx, 1      ; standard output 
    50 0000000A B9[00000000]                mov ecx, studentInfo    ; 'Program by Raphael Stein'
    51 0000000F BA23000000                  mov edx, infoLen
    52 00000014 CD80                        int 0x80
    53                                      
    54                                      ;Program Begins
    55                                  
    56                                      ; Ask for key input
    57 00000016 B804000000                  mov eax, 4      ; system call 4
    58 0000001B BB01000000                  mov ebx, 1      ; standard output 
    59 00000020 B9[23000000]                mov ecx, askForKey  ; 'Press key and Enter: '
    60 00000025 BA16000000                  mov edx, askLen 
    61 0000002A CD80                        int 0x80
    62                                      ; Take input
    63 0000002C B803000000                  mov eax, 3  ; system call 3 to get input
    64 00000031 BB00000000                  mov ebx, 0  ; standart input device
    65 00000036 B9[00000000]                mov ecx, key    ; pointer to id
    66 0000003B BA02000000                  mov edx, 2  ; take in this many bytes
    67 00000040 CD80                        int 0x80    
    68                                  
    69                                  
    70                                      
    71                                  control:        ; check if it's a control key
    72 00000042 B120                        mov cl, 32  ; space bar (32) is the first key after control keys
    73 00000044 BB[00000000]                mov ebx, key    ;move the first 8bits of ebx for comparison
    74 00000049 380B                        cmp byte [ebx], cl  ; compare 32 and the value of key 
    75 0000004B 7D1B                        jge printable   ; If the key is >=, it's a printable
    76 0000004D B804000000                  mov eax, 4
    77 00000052 BB01000000                  mov ebx, 1
    78 00000057 B9[39000000]                mov ecx, controlKey
    79 0000005C BA0D000000                  mov edx, controlLen
    80 00000061 CD80                        int 0x80
    81 00000063 E9A0000000                  jmp exit    ; It's obviously not any of the other categories
    82                                  
    83                                      
    84                                  printable:  ; Tell that it's a printable symbol
    85 00000068 B804000000                  mov eax, 4
    86 0000006D BB01000000                  mov ebx, 1
    87 00000072 B9[46000000]                mov ecx, printableKey
    88 00000077 BA0F000000                  mov edx, printableLen
    89 0000007C CD80                        int 0x80
    90                                  
    91                                  decimal: 
    92 0000007E B130                        mov cl, 48  ; 0 (48) is the smallest decimal
    93 00000080 BB[00000000]                mov ebx, key    ;move the first 8bits of ebx for comparison
    94 00000085 380B                        cmp byte [ebx], cl
    95 00000087 7C7F                        jl  exit
    96 00000089 B139                        mov cl, 57  ; 9 (57) is the largest decimal
    97 0000008B BB[00000000]                mov ebx, key    ;move the first 8bits of ebx for comparison
    98 00000090 380B                        cmp byte [ebx], cl
    99 00000092 7F18                        jg  uppercase   ; if key is greater, jump to check if it's                      uppercase.
   100 00000094 B804000000                  mov eax, 4
   101 00000099 BB01000000                  mov ebx, 1
   102 0000009E B9[55000000]                mov ecx, decimalKey
   103 000000A3 BA0D000000                  mov edx, decimalLen
   104 000000A8 CD80                        int 0x80
   105 000000AA EB5C                        jmp exit
   106                                  
   107                                  uppercase:
   108 000000AC B141                        mov cl, 65  ; A (65) is the smallest smallest uppercase
   109 000000AE BB[00000000]                mov ebx, key    ;move the first 8bits of ebx for comparison
   110 000000B3 380B                        cmp byte [ebx], cl
   111 000000B5 7C51                        jl  exit
   112 000000B7 B15A                        mov cl, 90  ; Z (90) is the largest upper case
   113 000000B9 BB[00000000]                mov ebx, key    ;move the first 8bits of ebx for comparison
   114 000000BE 380B                        cmp byte [ebx], cl
   115 000000C0 7F18                        jg  lowercase
   116 000000C2 B804000000                  mov eax, 4  ; If it IS an upper case key, print and then exit
   117 000000C7 BB01000000                  mov ebx, 1
   118 000000CC B9[62000000]                mov ecx, upperKey
   119 000000D1 BA10000000                  mov edx, upperLen
   120 000000D6 CD80                        int 0x80
   121 000000D8 EB2E                        jmp exit
   122                                  
   123                                          
   124                                  lowercase:
   125 000000DA B161                        mov cl, 97  ; a (97) is the smallest smallest uppercase
   126 000000DC BB[00000000]                mov ebx, key    ;move the first 8bits of ebx for comparison
   127 000000E1 380B                        cmp byte [ebx], cl
   128 000000E3 7C23                        jl  exit    ; If the key is less than 97 exit.
   129 000000E5 B17A                        mov cl, 122 ; Z (90) is the largest upper case
   130 000000E7 BB[00000000]                mov ebx, key    ;move the first 8bits of ebx for comparison
   131 000000EC 380B                        cmp byte [ebx], cl
   132 000000EE 7FEA                        jg  lowercase
   133 000000F0 B804000000                  mov eax, 4  ; If it IS an upper case key, print and then exit
   134 000000F5 BB01000000                  mov ebx, 1
   135 000000FA B9[72000000]                mov ecx, lowerKey
   136 000000FF BA10000000                  mov edx, lowerLen
   137 00000104 CD80                        int 0x80
   138 00000106 EB00                        jmp exit
   139                                      
   140                                  exit:
   141 00000108 B804000000                  mov eax, 4      ; system call 4
   142 0000010D BB01000000                  mov ebx, 1      ; standard output 
   143 00000112 B9[82000000]                mov ecx, blankLine  ; Print blank line before exiting
   144 00000117 BA01000000                  mov edx, blankLen
   145 0000011C CD80                        int 0x80
   146                                  
   147 0000011E B801000000                  mov eax, 1
   148 00000123 31DB                        xor ebx, ebx
   149 00000125 CD80                        int 0x80
   150                                  
Pygmy answered 22/4, 2013 at 19:12 Comment(0)
R
13

The numbers on the left are the binary output of the assembler, related to your source code lines.

First column is source code line

The second column is address or offset. For example 00000023 is the address where your prompt label askForKey: is.

Third column is binary value. For example if you look at your prompt text Press it translates directly to hex values 5072657373

52 00000014 CD80 int 0x80

reads like this:

source code line 52, offset 00000014 contains binary value CD80, compiled from instruction INT 0x80.

You can also see that the next line that has an address next to it is 57 00000016, where the 16 came to be from the 14 before + 2 bytes for CD80

Runlet answered 22/4, 2013 at 19:22 Comment(7)
If the second column is the address of the instruction, why is it jumping and not incrementing by one, or a consistent number?Pygmy
@Imray because not every line of source code produces the same amount of compiled output - some don't produce at all (comments) and some produce a lot (db '....' can produce an arbitrary length) So when you stack them up one by one, all of different sizes you get that 'jumping'Runlet
Why is the address for key 00000000?Pygmy
because of the segment instruction before it, which reset the calculated offset. Same as the main: after thatRunlet
Thanks! One more question if I may; Whenever there's a cmp instruction, the instruction code starts with a B. Is this the code for cmp? And is the digit following the B always the id of the register? Can you explain this instruction to me.Pygmy
@Imray I'm not sure where do you see that "B" but the way it works is all these output codes are paired in two to make a byte, for example CD80 is two bytes. CMP compares two operands and sets some flags, such as Z or C so the next instruction JGE, JE, JC etc knows what to do - it checks if a specific combination of flags is set and if that's the case the jump is performed, otherwise execution continues after the jump instruction. The flags are being manipulated by many instructions, which is why most often you will see the jump right after the one you wanted to modify them (such as cmp)Runlet
@Imray here's the opcodes for cmp in particular: css.csail.mit.edu/6.858/2010/readings/i386/CMP.htmRunlet

© 2022 - 2024 — McMap. All rights reserved.