2013-03-10 27 views
5

Tôi đang cố gắng tăng giá trị số bằng cách sử dụng lắp ráp nội tuyến trong C++. Lý do tôi làm theo cách đó là thực hành kỹ năng "lắp ráp nội tuyến" của tôi.Thay đổi giá trị số bằng cách sử dụng lắp ráp nội tuyến trong C++

Vâng đó là những gì tôi đã thực hiện cho đến nay:

void main() 
{ 
    int x; 
    cout << "Please enter a number "; 
    cin >> x; 
    cout << "The number you entered is: " << x << "\n"; 
    foo(&x); 
    cout << "The new number is: " << x; 
    cin >> x; 
} 

void foo(int *x) 
{ 
    __asm 
    { 
     inc [x] 
    }; 
} 

Và giá trị không bao giờ thay đổi.

+0

Bạn đang sử dụng trình biên dịch nào? MSVC? – Cameron

+0

Microsoft Visual Studio 2012 –

+5

Bạn có thể muốn tháo rời mã đã biên dịch và xem nó có làm những gì bạn mong đợi không. Tôi đã nhìn thấy loại điều này đi sai do quá ít hoặc quá nhiều. Bạn có thể tăng 'x' thay vì' * x'. –

Trả lời

7

Bạn đang tăng giá trị thực tế là x. X về ngôn ngữ lắp ráp là hằng số chứa địa chỉ của x biến (của hàm foo). Trong đó, có chứa địa chỉ của main 's x. Vì vậy, inc [x] làm tăng số lượng con trỏ. Bạn cần tăng giá trị được lưu trữ tại địa chỉ [x], như inc [[x]]. Tất nhiên bạn không thể làm điều đó trong một hướng dẫn trong ngôn ngữ lắp ráp vì bạn cần hai truy cập bộ nhớ: để biết trong đó giá trị được lưu trữ và thực tế là tăng giá trị. Vì vậy, tôi muốn tư vấn cho một mã như thế này:

push eax 
mov eax, [x] 
inc dword ptr [eax] 
pop eax 
+0

Cảm ơn bạn! Trong tò mò, tôi đã thử một cách khác dựa trên lời nói của bạn: mov eax, x; mov ebx, [eax]; inc [ebx] và tôi không thành công, giá trị vẫn giữ nguyên. –

+1

Đây là trợ giúp của MSVC cho bạn. Nó tự động dịch 'mov eax, x' để di chuyển giá trị biến. Vì vậy, về mặt kỹ thuật, bạn có thể thay thế dòng thứ hai của mã của tôi bằng 'mov eax, x'. Thực tế, 'x' này cho MSVC chỉ là một chỉ mục trong khung ngăn xếp. Trong ngôn ngữ assembly tinh khiết, bạn phải viết 'mov eax, [ebp + 8]' vì x là biến ngăn xếp đầu tiên. Và trong trường hợp bạn sử dụng quy ước gọi 'fastcall', bạn sẽ viết' inc [eax] ', giống như vậy. – Aneri

-3

x86 chỉ có thể tăng đăng ký chứ không phải bộ nhớ, vì vậy bạn cần di chuyển con trỏ đến thanh ghi. Tôi đã kết thúc với điều này:

__asm 
{ 
    mov eax, x 
    mov ebx, [eax] 
    inc ebx 
    mov [eax], ebx 
}; 
+5

Huh? Vô lý. 'INC' có thể hoạt động trên các toán hạng đăng ký hoặc bộ nhớ. –

+0

Nó hoạt động tốt cho tôi. –

+0

Đó là "hoạt động" bởi vì nó thêm một sự thêm vào. Nhưng 'inc [eax]' cũng sẽ hoạt động. –

0

Có lẽ nó là hữu ích để biết làm thế nào Visual C++ tăng giá trị của một int-con trỏ:

void foo(*x) 
{ 
    (*x)++; 
} 

Trong chế độ debug, nó được phiên dịch sang

(*x)++; 
mov   eax,dword ptr [x] 
mov   ecx,dword ptr [eax] 
add   ecx,1 
mov   edx,dword ptr [x] 
mov   dword ptr [edx],ecx 

Ở chế độ phát hành giống như câu trả lời của Aneri.

Các vấn đề liên quan