1. 程式人生 > >彙編兩個64位加法的實現

彙編兩個64位加法的實現

老師上課佈置的作業實現64位加法的實現

最開始事懵逼的  但是後面再 草稿本上畫了記憶體 中的存放以及幾個

si :源地址暫存器

bx:基址暫存器

di:目的地址暫存器

地址暫存器的使用再想了下就差不多寫出來了 先貼出原始碼  我會 一步一步 解釋原始碼 以及把 除錯中的記憶體截圖 給你們

在64位上寫彙編需要的dosbox 以及 masm一篇文章有寫  然後此次比上次多得東西是debug.exe 需要在網上 下載debug.exe

先貼出程式碼吧 後面再解釋

data segment
  x dw 1111h,5678h,8900h,4567h  ;dw代表字型單元讀完一個偏移量加2
  y dw 0f666h,4321h,1099h,0f432h  ;
  sum dd ?
data ends
;--------------------------------
code segment
assume cs:code,ds:data
start:
  mov ax,data       ;把資料段的值賦給ax
  mov ds,ax

  mov bx,offset x    ;將x的值得地址給bx
  lea si,y                 ;將y的值得地址給si
  mov di,offset sum;將sum地址的值給cx

  mov ax,[bx]          ;將bx的低位值給ax
  add  ax,[si]           ;相加
  mov [di],ax          ;將結果存在cx的低位中
  
  mov ax,[bx+2]
  adc  ax,[si+2]        ;高位相加
  mov [di+2],ax       ;將高位相加結果存在sum中

  mov ax,[bx+4]
  adc ax,[si+4]
  mov [di+4],ax

  mov ax,[bx+6]
  adc ax,[si+6]
  mov [di+6],ax

;  mov ds,ax
;-----
;  mov word ptr sum,ax
;  mov word ptr sum+2,cx
   adc [di+8],0h       ;將標誌位加入
;-----
  mov ax,4c00h
  int 21h
code ends
end start
程式碼詳解
寫出程式碼 存為add.asm 並放入d:\masm資料夾內


然後在執行中輸入cmd 在cmd中d:進入d盤 cd masm進入masm資料夾

鍵入命令 masm add.asm

鍵入命令 link add.obj 

敲擊4下回車


之後會在masm資料夾下存在 add.exe


這裡說下 add.exe是編譯執行出來的執行檔案 64位機 該檔案 可以在dosbox下執行

如果在cmd下執行會報錯

現在 就需要在 dosbox 下面 debug 本程式了

dos box 下面

鍵入 mount c d\:masm           該句意思是把d:\masm 虛擬為一個32位的c盤

鍵入 c:                                       進入虛擬的32位c盤 

鍵入 debug add.exe               debug你寫出的add.exe檔案


現在就可以除錯了

除錯時的基本命令

t  執行下一步

r 檢視所有暫存器  用得最多 如果你不知道在幹什麼 你就 r一下  檢視暫存器

d ds: 0 f  檢視ds段暫存器下的東西 用得也多

q 退出除錯  

先說這些 

下面可以愉快的除錯了

data segment
  x dw 1111h,5678h,8900h,4567h  ;dw代表字型單元讀完一個偏移量加2
  y dw 0f666h,4321h,1099h,0f432h  ;
  sum dd ?
data ends
;--------------------------------
code segment

這裡先看看 暫存器狀態

鍵入r


這裡可以看到 下一條執行的語句  mov ax,076A

以及各個暫存器的值 

鍵入 t

可以看到 ax的值變了執行了一步

由於程式碼太多這樣一直截圖很麻煩 就不一步一步的解釋了 就解釋關鍵的位置
assume cs:code,ds:data
start:
  mov ax,data       ;把資料段的值賦給ax
  mov ds,ax


  mov bx,offset x    ;將x的值得地址給bx
  lea si,y                 ;將y的值得地址給si
  mov di,offset sum;將sum地址的值給cx
  程式碼執行到這的時候很關鍵

  這三句話的意思 是把 x ,y  ,sum 的地址分別賦值給 bx si di 相當於指標 

  bx si di 是指標  而[bx] [si] 是他們的值


看到沒 這裡 bx si di 的值先後有變化 分別賦值了

他們在記憶體中的位置可以用d 來看

鍵入 d ds:0 f

鍵入 d 


看到沒 在記憶體中 bx 指向0000 就是之前x的資料 

                              si  指向0008 就是之前y的資料

                              di  指向0010 就是sum的資料


這裡可以清楚的看到 sum 的值存放在di0010所指向的記憶體中 值是0777

程式完成的加法是  1111h+ 0f666h 結果等於 10777關鍵是還有一個1呢

沒錯他就是到了 cy 就是 標誌位


看到沒ny 沒有標誌位變成了 cy 有標誌位

好了下面同理 盡情的玩耍吧 debug 很有趣

  mov ax,[bx]          ;將bx的低位值給ax

  add  ax,[si]           ;相加
  mov [di],ax          ;將結果存在cx的低位中

  下面相加這裡我就解釋一個 

  3條指令完成 x 和 y 的16位的相加 並將結果存在 了 sum 中 下面幾個同理  

   還是同樣的檢視記憶體
  mov ax,[bx+2]
  adc  ax,[si+2]        ;高位相加
  mov [di+2],ax       ;將高位相加結果存在sum中


  mov ax,[bx+4]
  adc ax,[si+4]
  mov [di+4],ax


  mov ax,[bx+6]
  adc ax,[si+6]
  mov [di+6],ax


;  mov ds,ax
;-----
;  mov word ptr sum,ax
;  mov word ptr sum+2,cx
   adc [di+8],0h       ;將標誌位加入

   這裡也非常重要 這句話加了一個0  看起來沒必要 其實是引入標誌位
;-----
  mov ax,4c00h
  int 21h
code ends
end start