簡體   English   中英

無法理解寄存器和變量之間的匯編mov指令

[英]Can't understand assembly mov instruction between register and a variable

我在Linux 64位上使用NASM匯編程序。 我無法理解某些帶有變量和寄存器的東西。 我創建一個名為“ msg”的變量:

 msg db "hello, world"  

現在,當我要寫入標准輸出時,將msg移至rsi寄存器,但是我不按位理解mov指令... rsi寄存器由64位組成,而msg變量具有12個符號,每個符號8位,這意味着msg變量的大小為12 * 8位,明顯大於64位。

因此,如何制作這樣的指令呢?
mov rsi, msg ,而不會溢出分配給rsi的內存。

還是rsi寄存器包含字符串的第一個符號的存儲位置,並且在寫入1個符號后將其更改為下一個符號的存儲位置?

抱歉,如果我寫的是完全廢話,我是組裝的新手,一會兒我就無法掌握它。

在NASM語法(與MASM語法不同)中, mov rsi, symbolmov rsi, symbol地址放入RSI。

mov rsi, [symbol]將加載從symbol開始的8個字節。 編寫這樣的指令時,您可以選擇一個有用的位置來加載8個字節。

mov   rsi,  msg           ; rsi  = address of msg
movzx eax, byte [rsi+1]   ; rax  = 'e' (upper 7 bytes zeroed)
mov   edx, [msg+6]        ; rdx  = ' wor' (upper 4 bytes zeroed)

請注意,可以使用mov esi, msg因為符號地址始終適合32位(在默認的“小”代碼模型中,所有靜態代碼/數據都位於2GB的虛擬地址空間中)。 NASM使用匯編時間常量(例如mov rax, 1 )為您進行了優化,但可能無法使用鏈接時間常量。 為什么大多數x64指令將32位寄存器的高位歸零

在寫入1個符號后,它會更改為下一個符號的存儲位置嗎?

不,如果您需要,必須增加inc rsi 沒有魔術。 指針就是您可以像其他整數一樣操作的整數,而字符串只是內存中的字節。

訪問寄存器不會神奇地修改它們。

有諸如lodsbpop類的指令從內存加載並遞增指針(分別為rsirsp ),但是x86沒有任何前/后遞增/遞減尋址模式,因此即使使用mov也無法獲得該行為如果你想要的話。 使用add / subinc / dec

免責聲明:我不熟悉您要處理的程序集的樣式,因此以下內容更為籠統。 特定的口味可能比我以前習慣的功能更多。 通常,程序集處理大小取決於處理器的單字節/字實體。 我已經在8位和16位處理器上做了大量工作,所以這就是我的答案所在。

關於匯編的一般說明:匯編就像是一種高級語言,只是您必須處理更多細節。 因此,如果您習慣使用C語言進行某些操作,則可以從那里開始,然后進一步細分該操作。

例如,如果您聲明了兩個要添加的變量,那么在C語言中這很簡單:

x = a + b;

在組裝中,您必須進一步分解:

mov R1, a  * get value from a into register R1
mov R2, b  * get value from b into register R2
add R1,R2  * perform the addition (typically goes into a particular location I'll call it the accumulator
mov x, acc * store the result of the addition from the accumulator into x

根據組裝和處理器的風格,您也許可以直接在加法指令中引用變量,但是就像我說的那樣,我必須查看所使用的特定風格。

對您的特定問題的評論:如果您有一串字符,則必須使用某種循環分別移動每個字符。 我將設置一個寄存器來包含您字符串的起始地址,然后在每個字符移動后遞增該寄存器。 它的作用類似於C中的指針。您將需要某種指示字符串的終止或其他值來指示字符串的大小,以便知道何時停止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM