2014-10-27 68 views
0

我使用的是英特爾處理器的nasm,只是爲了通知您我的情況。將位置存儲在變量中的彙編mov

因此,這裏是我的問題:

我有一個變量命名的POS應存儲記憶ADRESS像3998或這樣的事情。現在我想轉移到存儲在此var中的地址。我該怎麼做呢?它甚至有可能嗎?

,現在這就是我的代碼:

mov ax, 0xb800 ; Go to the adress of the video card 
mov ds, ax 

printloop: 
    cmp [pos], byte 0 ; check if the value stored in pos is not 0 
    je hang 
    mov [pos], byte 36 ; PROBLEM: what it should do: write the ascii symbol(here $) to the position stored in pos 
    sub [pos], byte 2 ; decrement address stored in pos by two 
    jmp printloop 

hang: ; just a hang loop when all is done 
    jmp hang 

pos db 3998 ; the var pos with the initialization address 3998, which is the down right corner 

是否有可能與一個變種?或者我必須使用註冊?我該怎麼做呢?

感謝您的回覆。

+0

你不能在一個字節中裝入3998。 – Michael 2014-10-27 21:11:02

+0

所以,它工作的很好,當我每次減少pos 6。然後它用一種很酷的模式填滿所有東西。當它變回2時,它在所有顏色變色之前停止。它只是到最後才改變。我發現,當我將ax增加到例如0xb8aa時,它會結束填充它。所以看起來,斧頭的位置會在灌裝結束的地方發生變化,但只有在每次減少兩個位置時纔會發生變化。我不能讓斧頭低於b800,因爲它不在圖形邊界內。這是我的錯誤還是硬件「問題」?還是應該將ds更改爲較低的數字?感謝您的幫助:) – Frozn 2014-10-28 20:27:15

+1

不要重複使用問題發佈新問題。如果您有新問題,請將其作爲單獨問題發佈。 – Michael 2014-10-29 06:17:38

回答

0

看起來你想要做的是使用間接尋址通過寄存器的內容:

mov bx, [pos] 
mov byte [bx], 36 

你也想用dw而不是db定義pos因爲3998是一個太大的值字節。

+0

由於OP使用nasm,似乎正在編寫實模式代碼,並聲明瞭'pos'作爲一個字節,我認爲他需要像'movzx bx,byte [pos]'/'mov byte [bx]這樣的東西, 36' – Michael 2014-10-27 21:11:32

+0

噢,我的壞,我的手指默認輸入'ebx'。 :) – 2014-10-27 21:12:11

+0

讓我解釋一下:我們將pos的值移到ebx。正確?然後我們實際將$移到該位置。 ptr是什麼意思?它是否將該號碼「轉換」爲地址? – Frozn 2014-10-27 21:12:16

0

一個問題是,如果我們處於實模式或v86模式下,段大小限制爲64 KB,因此我們不能使用DS的相同段地址來尋址pos標籤在framebuffer之外,另外用於尋址另一個位置,但位於framebuffer內部。

一種解決方案是使用第二個段寄存器,一個段寄存器用於尋址幀緩衝區,另一個用於尋址pos標籤的位置。 (@Frank科特勒:我總是喜歡利用自己的專業知識通知。)

mov ax, 0xb800 ; segment address of the framebuffer 
mov es, ax  ; store it into the ES segment register 

; not shown here,but with a DOS *.exe file we default use a separated DATA-segment 
; DS=CS if the label of pos is placed inside of our codesegment 
; (not needed if running as a DOS *.COM file) 
mov ax, cs  ; get the segment address of the code segment 
mov ds, ax  ; store it into the DS segment register 

printloop: 
cmp [pos], byte 0 ; check if the value stored in DS:pos is not 0 
je hang 
mov di, [pos]  ; get the offset address stored in DS:pos 
mov es:[di], byte 36 ; write the ascii symbol to the position stored in es:di 
sub [pos], byte 2 ; decrement address stored in DS:pos by two 
jmp printloop 

hang: ; just a hang loop when all is done 
jmp hang 

pos dw 3998 ; the (16 bit) offset address 3998, which is the down right corner 

也可以放置指令來獲得上述循環的偏移地址(只需要這一個指令倍)和減少DI寄存器,並比較循環內的DI寄存器,並替換以減少和檢查pos的內容。

+0

編譯它給了我這個行中操作碼和操作數錯誤的無效組合: mov es:[di],byte 36 完整的es:[di]也必須在括號中:[es:[ di]]? – Frozn 2014-10-28 10:11:25