int _tmain(int argc, _TCHAR* argv[])
{
return 0;
} Kiểu trả về của hàm là int, bộ đối quy định bắt buộc là int argc và _TCHAR* argv[]
Ý nghĩa giá trị trả về thì đã nói. Nói về ý nghĩa các biến của hàm.
int argc: argc là một biến quản lý độ dài của mảng argv[]
_TCHAR* argv[]: argv[]ở đây là một con mảng con trỏ kiểu _TCHAR(tương tự kiểu char). Nó quản lý dòng đầu tham số
đầu vào để truyền cho hàm main(sẽ nói rõ hơn trong phần dưới đây)
Bây giờ ngoài bộ đối tiêu chuẩn được quy định, chúng ta hoàn toàn có thể khai báo thêm các đối cần thiết hoặc muốn
truyền cho hàm main chẳng hạn. Ví dụ:
int _tmain(int argc, _TCHAR* argv[],int n,int myvar1,char myvar2, ...)
{
cout<<"\nGia tri integer thu nhat dc truyen cho ham la "<<n;
cout<<"\n ....";
return 0;
} Và cách truyền tham số cũng bất kì, truyền tham trị, con trỏ, tham chiếu ...
#include
using namespace ;
int n;
int _tmain(int argc, _TCHAR* argv[],int& n,int* myvar1,char myvar2, ...)
{
cout<<"\nnhap gia tri cua n ";
cin>>n;
cout<<"\n .....";
return 0;
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
UNIX
Một chương trình chuẩn trong UNIX
#include <iostream>
using namespace std;
int main(int argc,char* argv[],char* envp[])
{
return 0;
} argc và argv[] đã giải thích ở trên. Xem tham số char* envp[] có ý nghĩa gì? env = envirenment(môi trường). envp[] là một
mảng con trỏ kiểu char để quản lý các thông số về biến môi trường làm việc. Để dễ hiểu tôi không giải thích dài dòng
mà lấy ví dụ cụ thể để dễ trực quan.
Để biết môi trường bạn đang làm việc gồm có những tham số gì, trong hàm main chúng ta có thể dùng câu lệnh:
for(int i=0;;i++)
if(envp[i]!=NULL) cout<<"\n"<<envp[i]; Để hiểu về cơ
chế hoạt động của hàm main và chức năng của argc,argv[] chúng ta biên
dịch một chương trình mẫu.
Hãy tạo file 1.cpp với nội dung
#include <iostream>
using namespace std;
int main(int argc,char* argv[],char* envp[])
{
cout<<"\n Số lượng biến truyền vào từ đầu vào tiêu chuẩn "<<argc;
cout<<"\n Đó là : \n\t";
for(int i=0;i<n;i++)
cout<<"\n"<<argv[i];
cout<<"\n Các tham số môi trường mà bạn đang làm việc : \n";
for(int i=0;;i++)
if(envp[i]!=NULL) cout<<"\n"<<envp[i];
return 0;
} Chúng ta save file vừa tạo. Mở terminal và biên dịch
g++ 1.cpp # hoặc g++ 1.cpp -o 1 Sau đó chạy chương trình:
./a.out 2 "input info" "for test"# hoặc ./1 2 3 4 "input info" "for
test" Tôi đang ở windows nên chưa test trực tiếp trên hệ thống UNIX được
nhưng cũng có thể đọc được những thông tin thu được
trên kênh ra của chương trình:
Số lượng biến truyền vào từ đầu vào tiêu chuẩn : 4
Đó là :
argv[0] = a.out# hoặc 1
argv[1] = 2
argv[2] = input info
argv[3] = for test
Các tham số môi trường mà bạn đang làm việc :(Cái này tùy từng môi trường làm việc, tùy từng hệ thống và hệ điều hành và
chế độ làm việc hiện thời của bạn)
Một lời nho nhỏ nữa là argc nhỏ nhất là 1, vì đó là tham số tên của chương trình thực thi được truyền cho hàm.
Những hiểu biết ít ỏi này chia sẻ mong bạn hiểu hơn đôi chút về vấn đề bạn quan tâm!
Mình test một chương trình demo trên UNIX cho bạn xem để chắc chắn lại những gì mình đã giải thích ở trên:
Code chương trình:(lưu trong file 1.cpp)
#include <iostream>
using namespace std;
int main(int argc,char* argv[],char* envp[])
{
cout<<"\n\targc = "<<argc;
for(int i=0;i<argc;i++)
cout<<"\nargv["<<i<<"] = "<<argv[i];
cout<<"\n\tEnvirenment variables : ";
for(int i=0;;i++)
if(envp[i]!=NULL)cout<<"\nenvp["<<i<<"] = "<<envp[i];
return 0;
} Biên dịch:
g++ 1.cpp Thực thi:
./a.out 1 2 3 4 5 6 "abc" "def" "varn" "varn+1" "..." [mp@localhost ~]$
./a.out 1 2 3 4 5 6 "abc" "def" "varn" "varn+1" "..." Kết quả:
argc = 12
argv[0] = ./a.out
argv[1] = 1
argv[2] = 2
argv[3] = 3
argv[4] = 4
argv[5] = 5
argv[6] = 6
argv[7] = abc
argv[8] = def
argv[9] = varn
argv[10] = varn+1
argv[11] = ...
Envirenment variables :
envp[0] = ORBIT_SOCKETDIR=/tmp/orbit-mp
envp[1] = HOSTNAME=localhost.localdomain
envp[2] = IMSETTINGS_INTEGRATE_DESKTOP=yes
envp[3] = TERM=xterm
envp[4] = SHELL=/bin/bash
envp[5] = DESKTOP_STARTUP_ID=
envp[6] = XDG_SESSION_COOKIE=63c0e623426e1eb3c0e0462d0000000 c-1283367080.880570-2076814743
envp[7] = HISTSIZE=1000
envp[8] = GTK_RC_FILES=/etc/gtk/gtkrc:/home/mp/.gtkrc-1.2-gnome2
envp[9] = WINDOWID=41943183
envp[10] = GNOME_KEYRING_CONTROL=/tmp/keyring-Sh02yZ
envp[11] = IMSETTINGS_MODULE=SCIM
envp[12] = USER=mp
envp[13] = LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so
=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;0
1:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;
42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01
;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;
31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*
.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;
31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31
:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.
rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7
z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=
01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01
;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;3
5:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;3
5:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:
*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*
.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.
qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=
01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=0
1;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35
:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*
.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.a
ac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.mid
i=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=
01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;
36:*.spx=01;36:*.xspf=01;36:
envp[14] = SSH_AUTH_SOCK=/tmp/keyring-Sh02yZ/ssh
envp[15] = SESSION_MANAGER=local/unix:@/tmp/.ICE-unix/1727,unix/unix:/tmp/.ICE-unix/1727
envp[16] = USERNAME=mp
envp[17] = DESKTOP_SESSION=gnome
envp[18] = MAIL=/var/spool/mail/mp
envp[19] = PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/mp/bin
envp[20] = QT_IM_MODULE=xim
envp[21] = PWD=/home/mp
envp[22] = XMODIFIERS=@im=SCIM
envp[23] = GDM_KEYBOARD_LAYOUT=us
envp[24] = LANG=en_US.utf8
envp[25] = GNOME_KEYRING_PID=1720
envp[26] = GDM_LANG=en_US.utf8
envp[27] = GDMSESSION=gnome
envp[28] = SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
envp[29] = HISTCONTROL=ignoredups
envp[30] = HOME=/home/mp
envp[31] = SHLVL=2
envp[32] = GNOME_DESKTOP_SESSION_ID=this-is-deprecated
envp[33] = LOGNAME=mp
envp[34] = DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-p2Glb1F8UV,guid=37a94c72b2c254f646a8ec4200000019
envp[35] = LESSOPEN=|/usr/bin/lesspipe.sh %s
envp[36] = WINDOWPATH=1
envp[37] = DISPLAY=:0.0
envp[38] = G_BROKEN_FILENAMES=1
envp[39] = XAUTHORITY=/var/run/gdm/auth-for-mp-2rJaMK/database
envp[40] = COLORTERM=Terminal
envp[41] = _=./a.out
Thank to admin from: http://www.vndf.net/archive/index.php/t-7752.html
Khoquachoqua :D
Tổng số lượt xem trang
Chủ Nhật, 30 tháng 6, 2013
Thứ Sáu, 28 tháng 6, 2013
Các thao tác dừng GDB
trong console của GDB, để thực thi các lệnh của linux
(gdb) shell [lenh_linux]
ví dụ:
(gdb) shell clear
(gdb) shell ls
------------------------------------------
để set break point ở một vị trí nào đó:
(gdb) break [so_dong]
hoặc
(gdb) break [ten_ham]
ví dụ:
cần đặt breakpoint tại dòng thứ 10 trong main.c
(gdb) break 10
hoặc đặt breakpoint tại hàm main
(gdb) break main
------------------------------------------
để xóa breakpoint
(gdb) delete [so_thu_tu_break_point]
ví dụ
xóa breakpoint thứ 2
(gdb) delete 2
------------------------------------------
sau khi đã đặt breakpoint( hoặc ko cần đặt breakpoint tùy cách chúng ta debug), thì chúng ta bắt đầu chạy chương trình bằng lệnh sau
(gdb) run
------------------------------------------
muốn xem chương trình đã dừng ở đâu
(gdb) list
ở ví dụ của chúng ta chỉ có hàm main, do đó khi dùng lệnh list thì sẽ hiển thị duy nhất các dòng code của hàm main. Còn nếu chương trình đang chạy ở 1 function nào đó, ví dụ function aaaa thì sẽ list code của function đó.
------------------------------------------
chúng ta muốn chương trình chạy dòng lệnh kế tiếp thì trong gdb gõ
(gdb) next [so_dong]
nếu không có [so_dong ] thì dòng lệnh kế tiếp dòng lệnh hiện tại được thực thi, còn nếu có [so_dong] thì chương trình sẽ thực thi từ dòng lệnh hiện tại tới dòng lệnh [so_dong]
------------------------------------------
muốn chạy vào bên trong thân hàm
(gdb) step
------------------------------------------
muốn quay lại đầu hàm thì dùng lệnh
(gdb) return
------------------------------------------
muốn chương trình thực thi tiếp cho đến breakpoint kế hoặc đếnt hết chương trình
(gdb) continue
------------------------------------------
trong quá trình chạy debug chúng ta muốn xem một biến có giá trị bằng bao nhiêu
(gdb) display [ten_bien]
ví dụ: trong hàm main của chúng ta có biến date, mà muốn xem biến này chúng ta thực hiện lệnh
(gdb) display date
------------------------------------------
muốn in giá trị của 1 biến trong console
(gdb) print [ten_bien]
ví dụ
(gdb) print date
------------------------------------------
muốn in địa chỉ của biến
(gdb) print &[ten_bien]
ví dụ
(gdb) print &date
------------------------------------------
hiển thị kiểu dữ liệu của biến
(gdb) ptype [ten_bien]
hoặc
(gdb) whatis [ten_bien]
ví dụ
(gdb) ptype date
------------------------------------------
gán giá trị cho 1 biến
(gdb) set variable [ten_bien] = [value]
(gdb) continue
ví dụ:
(gdb) set variable date = 15
(gdb) continue
------------------------------------------
compile lại file thực thi
(gdb) make
Nguồn : http://mathhoang.blogspot.com/2010/12/huong-dan-debug-chuong-trinh-voi-gdb.html
Cái này không thể thiếu nhé :D
(gdb) shell [lenh_linux]
ví dụ:
(gdb) shell clear
(gdb) shell ls
------------------------------------------
để set break point ở một vị trí nào đó:
(gdb) break [so_dong]
hoặc
(gdb) break [ten_ham]
ví dụ:
cần đặt breakpoint tại dòng thứ 10 trong main.c
(gdb) break 10
hoặc đặt breakpoint tại hàm main
(gdb) break main
------------------------------------------
để xóa breakpoint
(gdb) delete [so_thu_tu_break_point]
ví dụ
xóa breakpoint thứ 2
(gdb) delete 2
------------------------------------------
sau khi đã đặt breakpoint( hoặc ko cần đặt breakpoint tùy cách chúng ta debug), thì chúng ta bắt đầu chạy chương trình bằng lệnh sau
(gdb) run
------------------------------------------
muốn xem chương trình đã dừng ở đâu
(gdb) list
ở ví dụ của chúng ta chỉ có hàm main, do đó khi dùng lệnh list thì sẽ hiển thị duy nhất các dòng code của hàm main. Còn nếu chương trình đang chạy ở 1 function nào đó, ví dụ function aaaa thì sẽ list code của function đó.
------------------------------------------
chúng ta muốn chương trình chạy dòng lệnh kế tiếp thì trong gdb gõ
(gdb) next [so_dong]
nếu không có [so_dong ] thì dòng lệnh kế tiếp dòng lệnh hiện tại được thực thi, còn nếu có [so_dong] thì chương trình sẽ thực thi từ dòng lệnh hiện tại tới dòng lệnh [so_dong]
------------------------------------------
muốn chạy vào bên trong thân hàm
(gdb) step
------------------------------------------
muốn quay lại đầu hàm thì dùng lệnh
(gdb) return
------------------------------------------
muốn chương trình thực thi tiếp cho đến breakpoint kế hoặc đếnt hết chương trình
(gdb) continue
------------------------------------------
trong quá trình chạy debug chúng ta muốn xem một biến có giá trị bằng bao nhiêu
(gdb) display [ten_bien]
ví dụ: trong hàm main của chúng ta có biến date, mà muốn xem biến này chúng ta thực hiện lệnh
(gdb) display date
------------------------------------------
muốn in giá trị của 1 biến trong console
(gdb) print [ten_bien]
ví dụ
(gdb) print date
------------------------------------------
muốn in địa chỉ của biến
(gdb) print &[ten_bien]
ví dụ
(gdb) print &date
------------------------------------------
hiển thị kiểu dữ liệu của biến
(gdb) ptype [ten_bien]
hoặc
(gdb) whatis [ten_bien]
ví dụ
(gdb) ptype date
------------------------------------------
gán giá trị cho 1 biến
(gdb) set variable [ten_bien] = [value]
(gdb) continue
ví dụ:
(gdb) set variable date = 15
(gdb) continue
------------------------------------------
compile lại file thực thi
(gdb) make
Nguồn : http://mathhoang.blogspot.com/2010/12/huong-dan-debug-chuong-trinh-voi-gdb.html
Cái này không thể thiếu nhé :D
Chủ Nhật, 9 tháng 6, 2013
AT&T vs INTEL
AT&T vs INTEL
Đây là 2 cú pháp của ngôn ngữ Assembly.Nó sẽ gây nhầm lẫn cho người học Intel rồi chuyền qua AT&T và ngược lại . Nói dài dòng vậy đủ rồi let 's begin:Prefixes : theo mình hiểu là cái gắn vào đầu 1 ký tự nào đó làm nó có 1 chút thay đổi nhỏ
Trong AT&T thì "%" sẽ được gắn vào đầu các thanh ghi và "$" gắn vào đầu các cái hằng số được gán vào
Trong Intel dùng hex và binary thì sẽ được gắn "h" và "b" ở phía sau hằng số.
VD:
Intel AT&T
mov eax,1 movl $1,%eax
mov ebx,0ffh movl $0xff,%ebx
int 80h int $0x80
Direction of operands: dẫn đến các phép toán (dịch hơi chuối vì mình ko pro mấy én lịt) ><
Nói chung chỗ này thì thể hiện rõ AT&T nó ngược với Intel làm mình nhiều khi hơi điên chỗ này ><
Intel syntax : tham số đầu là destination hay còn là đích , tham số sau là source tham số nguồn
AT&T syntax: tham số đầu là Source nguồn gốc tội lỗi , tham số sau là Destination đích
VD:
Intel AT&T
instr dest,source instr source,dest
mov eax,[ecx] movl (%ecx),eax
Chúng ta thấy ở vd hàng 2 bên intel [] còn bên AT&T () ???? kỳ hén
Memory Operands: Tính toán trên memory j đó dịch thế cũng được :D
Intel thì ta cũng đã thấy để lấy địa chỉ của thanh ghi thì thanh ghi sẽ được bao bọc bỏi []
AT&T thì được ()
VD
Intel AT&T
mov eax,ebx movl (%ebx),%eax
mov eax,[ebx+3] movl 3(%ebx),%eax
Qua vd trên ta thấy cấu truc của AT&T nó được che khuất hay ẩn hơn so với Intel
Sự khác nhau này làm mình cũng thấy khó khăn do ko quen lắm :(
nó ko viết rõ ràng cho mình hỉu :(
Intel AT&T
segreg:[base+index*scale+disp] %segreg:disp(base,index,scale)
À quên khi dùng trong kiểu này thì các hằng số mình ko thêm "$" khi trong () của AT&T nhé
VD
Intel AT&T
instr foo,segreg:[base+index*scale+disp] instr %segreg:disp(base,index,scale),foo
mov eax,[ebx+20h] movl 0x20(%ebx),eax
add eax,[ebx+ecx*2h] movl (%ebx,%ecx,0x2),%eax
lea eax,[ebx+ecx] leal (%ebx.%ecx),%eax
sub eax,[ebx+ecx*4h-20h] subl -0x20(%ebx,%ecx,0x4),%eax
Phần cuối là suffixes : hay còn gọi là phần gắn vào đuôi mấy cái chữ cái làm đổi nghĩa của nó đồ ó
Có thể thấy AT&T nó gợi nhớ cú pháp sau các opcode và nó còn tùy thuộc vào kích thước toán hạng
AT&T
'l' is long
w is word
b is byte
Đương nhiên Intel cũng thể hiện nhưng nó ghi ở các memory operands như byte word dword .....
VD
Intel AT&T
mov al.bl movb %bl.%al
mov ax,bx movw %bx,%ax
mov eax,ebx movl %ebx,%eax
mov eax,dword ptr [ebx] movl (%ebx),%eax
Tới đây hết dồi... Lần đầu viết bài nên có nhiều sai sót có j đừng ném gạch em nhé :D
Thank to http://www.imada.sdu.dk/Courses/DM18/Litteratur/IntelnATT.htm đã cho ta tài liệu này :D
và tôi ko quên http://translate.google.com đã giúp tui dịch :D
KHOQUACHOQUA nhé
Đăng ký:
Bài đăng (Atom)