Assembly Code彙編代碼Intel格式簡單指令總結

編編成程 發佈 2023-01-25T23:17:19.755962+00:00

再來追加幾個指令:leave - 在每個函數最後進行執行,會把ebp直接賦值給esp以此來摧毀整個stack frame. 同時會額外進行一把pop操作,這樣就把ebp出棧了,整個stack frame當前的棧頂值就是return address。


下面都為Intel格式的彙編,在objdump下可以用-M intel, 在gdb下可以set disassembly-flavor intel來指定



  • mov dst,src - 將src的值填到dst里
  • add dst,src - 將src加到dst里
  • sub dst,src - 將dst減去src
  • and dst,src - 將src於dst做邏輯與,並將結果放到dst
  • push xxx - 將xxx壓棧,64位就壓8個字節,32位就壓4個字節
  • pop xxx - 將棧頂數據塞到xxx,64位就彈8個字節,32位就彈4個字節,同時進行相關stack的shrink.比如pop rax,就是把棧頂的8個字節給了rax,同時棧進行shrink 8個字節
  • jmp xxx - 跳轉到地址xxx, 他通過把target address填入到rip(eip)寄存器達成
  • call xxx - call對應的函數地址xxx, 在執行這句之前,把下一個指令rip(eip)的內容壓棧以便在call函數之後進行return
  • cmp dst,src - 比較src和dst, 實現方式是從dst減去src, 同時更新對應的flags來給接下來的指令進行判斷(jle等)
  • jle xxx - 如果之前的cmp操作的結果src是less than或者equal dst,那麼就進行跳轉
  • jge xxx - 同上,只要之前cmp操作的src大於等於dst就跳轉
  • jnz xxx - 當zero flag不為true的時候進行跳轉,否則執行下一句
  • jz xxx - 當zero flag為true的時候進行跳轉,否則執行下一句
  • lea dst,src - 進行地址加載,把src的address加載進dst,比如lea rdi, [rbx+0x10], 但是請注意,這裡的[rbx+0x10]並不是解引用的意思,只是把rbx的本身的值+0x10而已,而不是對其解引用 通過上面我們可以看到,我們在運行之後輸出了rdi的值 - 0x555555556005, 這也正好是我們在一開始對rip進行+0xe23的內容,這裡的rip需要特別注意,你在斷點的時候,這個rip表示的當前行號,因為此時還沒運行,當你真的運行到他的時候,rip的值已經是下一行也就是這裡的0x5555555551e2,而不是0x5555555551db, 這再一次證明了這裡的lea xxx,[yyy]的時候這裡的[yyy]並不是對yyy所指向內存的內容的解引用,而只是簡單的對yyy的值進行計算。同時我們還可以看到"#"後面的注釋,他已經直接幫我們把0x555555556005這個值給列印出來了,這個列印的值就是執行完當前語句之後的rip+0xe23=0x5555555551e2+0xe23=0x555555556005
  • int value - 生成軟中斷value,一般用來進行system calls


同時注意在進行反彙編的時候往往在rsp,rbp開棧有下面這些句子


這三行其實是額外的代碼用來進行16位元組對齊的,這樣可以加快效率




再來追加幾個指令:

  • leave - 在每個函數最後進行執行,會把ebp直接賦值給esp以此來摧毀整個stack frame. 同時會額外進行一把pop操作,這樣就把ebp出棧了,整個stack frame當前的棧頂值就是return address(之前調用函數的eip/rip)
  • ret - 這個就很明顯在,在當前棧頂之後return address的情況之下,把return address進行pop, 同時把eip/rip的值設置為這個address,這樣下一句就會直接調用這個地址
  • deference [] - 如果你看到了bracket, 這表示解引用, 類似於C下的*ptr. 比如這裡的 mov rax, rdx實際上是把rdx里的內容address塞到rax里,但是如果你是 mov rax, [rdx]實際上就是把rdx的指向的memory address所在的內容賦值給rax, 類似於auto val = p以及auto val = *p的區別。當然你甚至可以反過來 - mov [rax], rdx - 這裡的意思就表示把rdx存的memory address塞到rax所指內存的本身的值上去,類似*p = val, 此時rax的值不變,因為他所持有的memory address仍然不變
  • xor rdx,rax - 對rdx以及rax進行異或,同時把結果存入rdx, 如果rdx和rax是相同的值或者你直接xor rdx,rdx,這個就相當於清空了rdx,把rdx全部設置為0
關鍵字: