我正試圖學習x86程序集。我正在使用的書是Assembly Language - Step by Step, Programming With Linux
(我不得不說它很好)。到目前爲止,我學到了很多東西,但我覺得自己也應該挑戰自我,在很多方面保持領先地位,這樣我就可以更快地學習(我可以繼續學習,自上而下學習,但是我覺得它很乏味慢)。x86程序集:在mul(seg故障)後向控制檯輸出整數
所以,我認爲嘗試乘兩個寄存器(32位)然後將數據輸出到控制檯是一個很酷的主意。
問題是,當我執行程序時(我正在使用NASM,就像本書所做的那樣 - 雖然沒有Insight調試器),但我收到了一個分段錯誤。我在gdb中進行了相當數量的調試,但是出於某種原因,我似乎無法弄清楚問題所在。
我想知道我爲什麼會收到分段錯誤,以及 譴責此問題的好方法。另外,如果我在代碼中所做的評論與實際發生的事情不匹配,如果有人能糾正我的錯誤,我將不勝感激。
這是我的代碼到目前爲止(它很好評論)
謝謝。
德codez
section .data
;TODO
section .bss
valueToPrint: resb 4 ;alloc 4 bytes of data in 'valueToPrint'
section .text
global _start
_mul:
mov eax, 0x2A ;store 42 in eax
mov edx, 0x2A ;store 42 in edx
mul eax
ret
_safe_exit:
mov eax, 1 ;initiate 'exit' syscall
mov ebx, 0 ;exit with error code 0
int 0x80 ;invoke kernel to do its bidding
_start:
nop ;used to keep gdb from complaining
call _mul ;multiply the values
mov [valueToPrint], eax ;store address of eax in the contents of valueToPrint
mov eax, 4 ;specify a system write call - aka syswrite
mov ebx, 1 ;direction used to make the syswrite call output to console - i.e. stdout
mov dword [ecx], valueToPrint ;store valueToPrint in ecx: ecx represents the syswrite register
int 0x80 ;invoke kernel based on the given parameters
call _safe_exit
編輯
而且,我跑Arch Linux的,如果有差別。
,使用了'MUL eax',它乘EAX,EAX與...因爲你在eax和edx中都使用了42,你會得到(當然,你會得到)正確的答案,但是你不涉及edx中的值。 @Adam Rosenfield(下面)雖然有正確的答案,但您並不是首先創建要打印的TEXT/ASCII字符串。程序集並不會自動爲你做任何事情。這就是爲什麼你有這麼多控制權但你必須告訴它如何去做所有事情。您不會創建txt字符串來指示ecx進行打印。 (你還需要一個長度) – lornix
此外,'mul'(乘法)將eax(ax/rax等)中的值與指定的值相乘,並將得到的64位值放入EDX:EAX中。如果你'重新尋找完整的答案,記得也使用edx值。 42 * 42 = 1764,所以你遠離edx的答案,但你仍然應該知道發生了什麼,所以你可以期望edx改變,如果需要可用。 – lornix
(天哪,我今晚很健談!)小挑剔的東西....你的'_safe_exit'子程序...因爲它永遠不會返回,所以你應該用'jmp'來代替它。是的,當程序退出時,系統會丟棄所有內容......但是,您應該知道事情是如何工作的。 'call _save_exit'很好,但對我來說,它會在堆棧中留下一個值。挑剔的東西。我很抱歉。當我開始在16K機器上裝配時,內存很貴,而且你編寫了嚴格的代碼。我仍然這麼想,即使是8G的RAM。一般來說運行速度更快。 – lornix