我想結合c和匯編代碼。
我有以下C代碼:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern void _increment(unsigned short *x);
int main(int argc, char** argv)
{
unsigned short x = 0;
_increment(&x);
printf("%d", x)
return 0;
}
以及組件(32位NASM)代碼:
section .text
global _increment
_increment:
push ebx
mov bx, word [esp+8] ;what is stored in bx here? the x address?
mov ax, [bx] ;what is stored in ax here? the x value?
;add word [esp+8], 1 -> dosnt work
pop ebx
ret
section .data
如果執行此操作,則會出現分段錯誤。有人能解釋寄存器/堆棧中存儲的內容嗎?也許我可以增加值而不是X的地址?
很明顯,您了解指針的工作原理,唯一的錯誤是指針本身的大小。在幾乎所有的CPU上,指針的大小(而不是它指向的對象的大小)將等于指令指針寄存器的大小(通常稱為PC,用于non-x8 6 architectures.上的程序計數器)。這一規則有例外,但通常它只會匹配硬件的默認寄存器大小。這就是為什么,正如您在評論中提到的,您只加載了一半的指針,因為您使用了
bx
作為從堆棧加載的目標。在x86中,不在括號中的寄存器操作數決定了要讀/寫內存的字節數。這就是為什么在執行mov bx, word [esp+8]
時,即使esp
是32-bit,而bx
是16-bit,也不會因為操作數大小不匹配而出現匯編錯誤;右操作數是16-bit內存,而不是32-bit寄存器。