2
如果我使用寄存器而不是內存,它爲什麼不打印字符?爲什麼我不能在這裏使用註冊?
這裏的代碼:
mov eax,97
mov ebp,eax
call print_char
print_char:
pusha
mov eax,4
mov ebx,1
mov ecx,ebp
mov edx,1
int 80h
popa
ret
如果我使用寄存器而不是內存,它爲什麼不打印字符?爲什麼我不能在這裏使用註冊?
這裏的代碼:
mov eax,97
mov ebp,eax
call print_char
print_char:
pusha
mov eax,4
mov ebx,1
mov ecx,ebp
mov edx,1
int 80h
popa
ret
這並不是說你不能用一個寄存器...這是你沒有提供的地址的字符串(特別是C字符串,一個空結束字符數組)。對於那些不熟悉int 80h
system calls在Linux上
快速背景資料,這裏是在x86的calling convention:
System call # - eax
Parameters - ebx, ecx, edx, esi, edi, ebp
所以,you're calling system call 4,這是sys_write
。與c的簽名是:
ssize_t sys_write(unsigned int fd, const char * buf, size_t count)
可以看到,第二個參數(ecx
)被認爲是一個const char* buf
,這是一個指向一個字符串。您正在通過97
,這當然不是有效的地址,而且您可能存在分段錯誤。
您例如快速和骯髒的方法,它使用堆棧來存儲一個字符的字符串:
print_char: # Takes char in ebp
pusha
mov eax, 4 # sys_write
mov ebx, 1 # stdout
push ebp
mov ecx, esp # buf (char on stack)
mov edx, 1 # just one character
int 80h # linux syscall
pop ebp
popa
ret
這應該打印的字母「A」(ASCII 97)到標準輸出。如果你想打印一個十進制97,那麼就像在C中一樣,你會從printf
家族中調用一些東西,你需要將該十進制數字轉換爲字符串,然後再將它寫入stdout
。
1 - 技術上的字符串並不需要以null終止的,因爲在這裏你可以指定打印一個字符。