如何阅读NASM汇编程序的.lst清单文件

10
我写了一个NASM程序,并使用nasm -f elf -l rs.lst rs.asm命令从中创建了一个清单文件。 这个程序完美地接收一个关键输入值,然后输出该值是控制键还是可打印键,如果是数字,小写或大写字母则输出相应内容。
我需要帮助理解.lst文件中的内容。左边的数字是否代表地址?指令?它们表示内存吗? 以下是.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                                  
1个回答

13

左侧的数字是汇编程序的二进制输出,与源代码行相关。

第一列是源代码行。

第二列是地址或偏移量。例如,00000023 是标签 askForKey: 的位置。

第三列是二进制值。例如,如果您查看提示文本 Press,它直接转换为十六进制值 5072657373

52 00000014 CD80 int 0x80

读作:

源代码行 52,偏移量 00000014 包含由指令 INT 0x80 编译得到的二进制值 CD80。

您还可以看到下一行旁边有一个地址,即 57 00000016,其中 16 来自前面的 14 加上 2 字节的 CD80。


@Imray 因为并非每一行源代码产生的编译输出都相同 - 有些根本不产生(注释),而有些则会产生大量输出(db '....' 可以产生任意长度)。因此,当你将它们逐个堆叠起来时,由于大小不同,就会出现“跳跃”的情况。 - Sten Petrov
2
因为在它之前有 segment 指令,它会重置已计算的偏移量。与主函数类似,在这之后也是如此。 - Sten Petrov
谢谢!如果可以的话,我还有一个问题:每当出现cmp指令时,指令代码都以B开头。这是cmp的代码吗?而且,紧随其后的数字是否总是寄存器的ID?你能向我解释一下这个指令吗? - CodyBugstein
1
@Imray,我不确定你在哪里看到了那个“B”,但它的工作方式是所有这些输出代码都成对出现以形成一个字节,例如CD80就是两个字节。CMP比较两个操作数并设置一些标志,例如Z或C,因此下一条指令JGE、JE、JC等知道该做什么——它检查是否设置了特定组合的标志,如果是,则执行跳转,否则在跳转指令之后继续执行。许多指令都会操纵这些标志,这就是为什么大多数情况下您会看到您想要修改它们(如cmp)之后紧接着跳转的原因。 - Sten Petrov
1
@Imray 这里是特定于 cmp 的操作码:http://css.csail.mit.edu/6.858/2010/readings/i386/CMP.htm - Sten Petrov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接